1
\$\begingroup\$

i want to calculate the uptime of LPC 1768 from when it begins running. for example a function like millis(); in arduino.

\$\endgroup\$
2
\$\begingroup\$

I suggest that you setup a hardware timer that increments a counter every milisecond. By reading this value you will know your uptime.

\$\endgroup\$
  • \$\begingroup\$ "you will know your uptime" .... modulo the size of the counter, of course. A millisecond counter, for example, will overflow after only a couple of months, if it is only 32 bit unsigned... \$\endgroup\$ – Brian Drummond Jan 8 '16 at 11:57
  • 1
    \$\begingroup\$ Of course. But you may handle the counter overflow in an interrupt and increase a "high bits" variable. Overflow of that variable would require milleniums if it's u_int32... \$\endgroup\$ – Blup1980 Jan 8 '16 at 14:53
0
\$\begingroup\$

I use the following code which uses the RIT peripheral (Repetitive Interrupt Timer). This is a very simple timer peripheral. This will let you use the full featured timers and the ARM system tick timer for other uses:

volatile uint32_t rit_high = 0;

static void rit_irq_handler()
/////////////////////////////
{
  // Clear interrupt pending flag:
  LPC_RIT->RICTRL = (1<<0) |  // clear interrupt flag
                    (1<<1) |  // clear counter on overflow
                    (1<<3);   // timer enable

  // increase high counter:
  rit_high++;

  // memory barrier. Makes sure that the interrupt pending flag
  // gets written before we exit the ISR
  __DMB();  
}



void stopwatch_start (void)
///////////////////////////
{
  NVIC_DisableIRQ(RIT_IRQn);

  rit_high = 0;

  // configure and set handler to highestpriority:
  NVIC_SetVector(RIT_IRQn, (uint32_t)rit_irq_handler);
  NVIC_SetPriority(RIT_IRQn, 0);

  // power on the Repeative Interrupt Timer:
  LPC_SC->PCONP     |= (1<<16);

  // init timer with defaults:
  LPC_RIT->RICOUNTER = 0;
  LPC_RIT->RICOMPVAL = ~0;
  LPC_RIT->RIMASK    = 0;

  LPC_RIT->RICTRL    = (1<<0) |  // clear interrupt flag
                       (1<<1) |  // clear counter on overflow
                       (1<<3);   // timer enable

  NVIC_EnableIRQ(RIT_IRQn);
}


void stopwatch_stop (void)
//////////////////////////
{
  NVIC_DisableIRQ(RIT_IRQn);

  LPC_RIT->RICTRL = (1<<0) |  // clear interrupt flag
                    (1<<1) |  // clear counter on overflow
                    (0<<3);   // timer disable
}

static uint64_t stopwatch_getval (void)
//////////////////////////////////////
{
  return (uint64_t(rit_high)<<32) | LPC_RIT->RICOUNTER;
}


uint64_t stopwatch_getclk (void)
////////////////////////////////
{
  uint64_t a,b;
  a = stopwatch_getval();
  while (1)
  {
    b = stopwatch_getval();
    if (b>=a) return b;
    a = b;
  }
}


uint32_t stopwatch_getms (void)
///////////////////////////////
{
  return stopwatch_getclk() / (CORE_FREQ/1000);
}


uint64_t stopwatch_getus (void)
///////////////////////////////
{
  return stopwatch_getclk() / (CORE_FREQ/1000000);
}

Set CORE_FREQ to the speed of the RIT peripheral, by default that's your CPU frequency divided by 4. If you want the timer to run at full CPU speed you can do so by reprogramming the PCLKSEL1 register like this:

  // RIT: Set perpheral clock divider to 1:
  LPC_SC->PCLKSEL1 = (LPC_SC->PCLKSEL1 & ~(3<<26)) | (1<<26);

You want to do this before activating the PLL0 (reason for this is in the LPC1768 errata document), so this code should be placed in your system startup. This is likely the file system_LPC17xx.c.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.