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.

Dependents:   nRF51_rtc_example LoRa_PIR BLE_Lightning_sensor BLE_AlarmWatch ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers nrf51_rtc.cpp Source File

nrf51_rtc.cpp

00001 #include "nrf51_rtc.h"
00002 
00003 int nrf51_rtc::set_time(time_t rawtime) {
00004     // set the current time from a parameter
00005     time_base = rawtime;
00006     rtc_previous = int (NRF_RTC1->COUNTER) / ticks_per_second;
00007     return 0;
00008 }
00009 
00010 time_t nrf51_rtc::time() {
00011     // get the current time... and update the underlying variables for tracking time
00012     //  ...this routine must be called regularly, before the 24b RTC register can wrap around:  
00013     //  t < size of register / (LFCLK_FREQUENCY / (NRF_RTC1->PRESCALER + 1))
00014     //    size of register = 2^24 ticks 
00015     //    LFCLK_FREQUENCY = 2^15 cycles/sec 
00016     //    NRF_RTC1->PRESCALER = 0 -- as (currently) set by mbed library!
00017     //  = (2^24)/(2^15/1) = 2^9 seconds = 512 seconds, ~ 8.5 minutes
00018     unsigned int rtc_now = (NRF_RTC1->COUNTER) / ticks_per_second;
00019     unsigned int delta_seconds = ((rtc_now + counter_size_in_seconds) - rtc_previous) % counter_size_in_seconds;
00020     time_base = time_base + (time_t) delta_seconds;
00021     rtc_previous = rtc_now;
00022     return time_base;
00023 }
00024 
00025 void nrf51_rtc::update_rtc() {
00026     // for use as interrupt routine, same as "time" but doesn't return a value (as req'd for interrupt)
00027     //  ...but this is useless since the compiler seems to be unable to correctly attach a member function to the ticker interrupt
00028     //  ...the exact same interrupt routine attached to a ticker works fine when declared outside the method
00029     nrf51_rtc::time();
00030 }
00031 
00032 nrf51_rtc::nrf51_rtc() {
00033     rtc_previous=0;
00034     time_base=0;
00035     #define LFCLK_FREQUENCY 0x8000
00036     #define RTC_COUNTER_SIZE 0x1000000
00037     ticks_per_second = LFCLK_FREQUENCY / (NRF_RTC1->PRESCALER + 1);
00038     counter_size_in_seconds = RTC_COUNTER_SIZE / ticks_per_second;
00039     
00040     // Ticker inside the method doesn't work:  the interrupt attachment to the ticker messes up the world (code goes to the weeds)
00041     //  ... not needed if "rtc.time()" is called frequently enough (once per 512 seconds)
00042     //  ... this scheme (ticker+interrupt routine to update rtc) works correctly when implemented at the next level up
00043     //Ticker rtc_ticker;
00044     //#define RTC_UPDATE 1
00045     //rtc_ticker.attach(this,&nrf51_rtc::update_rtc, RTC_UPDATE); // update the time regularly (must be < duration of 24b timer)
00046 }