An attempt to provide a Real Time Clock for the nRF51-DK. This code provides rtc.time and rtc.set_time replacements for the similarly named C standard methods (unimplemented for nRF51-DK last I checked). Not very well tested, but it seems to work for simple applications.

Fork of nrf51_rtc by Francis Schumacher

nrf51_rtc.cpp

Committer:
lionello
Date:
2015-04-16
Revision:
3:9be93d7808ca
Parent:
2:e1479e6ffc37

File content as of revision 3:9be93d7808ca:

#include "nrf51_rtc.h"

#include <mbed.h>

#define LFCLK_FREQUENCY 0x8000
#define RTC_COUNTER_MASK 0xFFFFFF

nrf51_rtc rtc;


int nrf51_rtc::set_time(time_t rawtime) {
    rtc_previous = NRF_RTC1->COUNTER;
    // set the current time from a parameter
    time_base = rawtime;    
    return 0;
}

time_t nrf51_rtc::time() {
    // get the current time... and update the underlying variables for tracking time
    //  ...this routine must be called regularly, before the 24b RTC register can wrap around:  
    //  t < size of register / (LFCLK_FREQUENCY / (NRF_RTC1->PRESCALER + 1))
    //    size of register = 2^24 ticks 
    //    LFCLK_FREQUENCY = 2^15 cycles/sec 
    //    NRF_RTC1->PRESCALER = 0 -- as (currently) set by mbed library!
    //  = (2^24)/(2^15/1) = 2^9 seconds = 512 seconds, ~ 8.5 minutes

    uint32_t rtc_now = NRF_RTC1->COUNTER;
    uint32_t delta_ticks = (rtc_now - rtc_previous) & RTC_COUNTER_MASK;

    uint32_t delta_seconds = delta_ticks / ticks_per_second;
    time_base += delta_seconds;
    uint32_t missing_ticks = delta_ticks - delta_seconds * ticks_per_second;
    rtc_previous = rtc_now - missing_ticks;
    return time_base;
}

void nrf51_rtc::update_rtc() {
    // for use as interrupt routine, same as "time" but doesn't return a value (as req'd for interrupt)
    rtc.time();
}

nrf51_rtc::nrf51_rtc() :
    ticks_per_second(LFCLK_FREQUENCY / (NRF_RTC1->PRESCALER + 1))
{
    rtc_previous=0;
    time_base=0;

    
    // Ticker inside the method doesn't work:  the interrupt attachment to the ticker messes up the world (code goes to the weeds)
    //  ... not needed if "rtc.time()" is called frequently enough (once per 512 seconds)
    //  ... this scheme (ticker+interrupt routine to update rtc) works correctly when implemented at the next level up
    //Ticker rtc_ticker;
    //#define RTC_UPDATE 1
    //rtc_ticker.attach(this,&nrf51_rtc::update_rtc, RTC_UPDATE); // update the time regularly (must be < duration of 24b timer)
}