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

Committer:
fxschumacher
Date:
Sun Feb 08 01:28:47 2015 +0000
Revision:
0:3677a016109b
Initial revision -- library to implement Real Time Clock (time and set_time) for nRF51-DK.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fxschumacher 0:3677a016109b 1 #include "nrf51_rtc.h"
fxschumacher 0:3677a016109b 2
fxschumacher 0:3677a016109b 3 int nrf51_rtc::set_time(time_t rawtime) {
fxschumacher 0:3677a016109b 4 // set the current time from a parameter
fxschumacher 0:3677a016109b 5 time_base = rawtime;
fxschumacher 0:3677a016109b 6 rtc_previous = int (NRF_RTC1->COUNTER) / ticks_per_second;
fxschumacher 0:3677a016109b 7 return 0;
fxschumacher 0:3677a016109b 8 }
fxschumacher 0:3677a016109b 9
fxschumacher 0:3677a016109b 10 time_t nrf51_rtc::time() {
fxschumacher 0:3677a016109b 11 // get the current time... and update the underlying variables for tracking time
fxschumacher 0:3677a016109b 12 // ...this routine must be called regularly, before the 24b RTC register can wrap around:
fxschumacher 0:3677a016109b 13 // t < size of register / (LFCLK_FREQUENCY / (NRF_RTC1->PRESCALER + 1))
fxschumacher 0:3677a016109b 14 // size of register = 2^24 ticks
fxschumacher 0:3677a016109b 15 // LFCLK_FREQUENCY = 2^15 cycles/sec
fxschumacher 0:3677a016109b 16 // NRF_RTC1->PRESCALER = 0 -- as (currently) set by mbed library!
fxschumacher 0:3677a016109b 17 // = (2^24)/(2^15/1) = 2^9 seconds = 512 seconds, ~ 8.5 minutes
fxschumacher 0:3677a016109b 18 unsigned int rtc_now = (NRF_RTC1->COUNTER) / ticks_per_second;
fxschumacher 0:3677a016109b 19 unsigned int delta_seconds = ((rtc_now + counter_size_in_seconds) - rtc_previous) % counter_size_in_seconds;
fxschumacher 0:3677a016109b 20 time_base = time_base + (time_t) delta_seconds;
fxschumacher 0:3677a016109b 21 rtc_previous = rtc_now;
fxschumacher 0:3677a016109b 22 return time_base;
fxschumacher 0:3677a016109b 23 }
fxschumacher 0:3677a016109b 24
fxschumacher 0:3677a016109b 25 void nrf51_rtc::update_rtc() {
fxschumacher 0:3677a016109b 26 // for use as interrupt routine, same as "time" but doesn't return a value (as req'd for interrupt)
fxschumacher 0:3677a016109b 27 // ...but this is useless since the compiler seems to be unable to correctly attach a member function to the ticker interrupt
fxschumacher 0:3677a016109b 28 // ...the exact same interrupt routine attached to a ticker works fine when declared outside the method
fxschumacher 0:3677a016109b 29 nrf51_rtc::time();
fxschumacher 0:3677a016109b 30 }
fxschumacher 0:3677a016109b 31
fxschumacher 0:3677a016109b 32 nrf51_rtc::nrf51_rtc() {
fxschumacher 0:3677a016109b 33 rtc_previous=0;
fxschumacher 0:3677a016109b 34 time_base=0;
fxschumacher 0:3677a016109b 35 #define LFCLK_FREQUENCY 0x8000
fxschumacher 0:3677a016109b 36 #define RTC_COUNTER_SIZE 0x1000000
fxschumacher 0:3677a016109b 37 ticks_per_second = LFCLK_FREQUENCY / (NRF_RTC1->PRESCALER + 1);
fxschumacher 0:3677a016109b 38 counter_size_in_seconds = RTC_COUNTER_SIZE / ticks_per_second;
fxschumacher 0:3677a016109b 39
fxschumacher 0:3677a016109b 40 // Ticker inside the method doesn't work: the interrupt attachment to the ticker messes up the world (code goes to the weeds)
fxschumacher 0:3677a016109b 41 // ... not needed if "rtc.time()" is called frequently enough (once per 512 seconds)
fxschumacher 0:3677a016109b 42 // ... this scheme (ticker+interrupt routine to update rtc) works correctly when implemented at the next level up
fxschumacher 0:3677a016109b 43 //Ticker rtc_ticker;
fxschumacher 0:3677a016109b 44 //#define RTC_UPDATE 1
fxschumacher 0:3677a016109b 45 //rtc_ticker.attach(this,&nrf51_rtc::update_rtc, RTC_UPDATE); // update the time regularly (must be < duration of 24b timer)
fxschumacher 0:3677a016109b 46 }