This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Best way to implement micros() function in nrf51822?

I need to implement the micros() function of arduino on nrf51822. Can someone guide me on how it can be done?

This the function for Arduino:

    unsigned long micros() {
    unsigned long m;
    uint8_t oldSREG = SREG, t;
 
    cli();
    m = timer0_overflow_count;
#if defined(TCNT0)
    t = TCNT0;
#elif defined(TCNT0L)
    t = TCNT0L;
#else
    #error TIMER 0 not defined
#endif


#ifdef TIFR0
    if ((TIFR0 & _BV(TOV0)) && (t & 255))
        m++;
#else
    if ((TIFR & _BV(TOV0)) && (t & 255))
        m++;
#endif

    SREG = oldSREG;
 
    return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}

Basically the function returns the number of microseconds since the board started running.

Parents
  • Simple, although a bit power hungry. You use one of the two TIMER modules available to you, whichever one you're not using for anything else. Set it up to count in microseconds, ie a divisor of 16, which means a prescalar of 4.

    The two TIMERS the softdevice doesn't use have a resolution of 16 bits only, so add an interrupt on TASKS_CLEAR and when you get it, increment another variable which counts units of 65536 microseconds.

    When you want the micros() value you read the timer, add on your counter shifted by 16 bits, that's the micros since you started this timer running. Start that right after reset.

    So several things here. One - this will keep the HFCLK running constantly and that takes power. Two the max microseconds which fits in 32 bits is about 4300 or just over an hour. If you want more than that you'll need to use a uint64 or split the time into two 32-bit values.

    Do you really need microsecond precision for your app? If you really need say millisecond precision, you could use the RTC, which is lower power, counts slower and has more bits so you rarely need to roll it over.

  • Yes I do need the microsecond precision.

    Can you please show me how to:

    1. Put an interrupt on TASKS_CLEAR? Is it by setting the compare CC[0] on 255?
    2. How to read the timer at an instant? I tried searching the manual but wasn't able to find anything.
Reply Children
No Data
Related