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
Revision 3:9be93d7808ca, committed 2015-04-16
- Comitter:
- lionello
- Date:
- Thu Apr 16 11:43:56 2015 +0000
- Parent:
- 2:e1479e6ffc37
- Commit message:
- Fixed clock drift by keep tracking of the fractional seconds (ticks)
Changed in this revision
nrf51_rtc.cpp | Show annotated file Show diff for this revision Revisions of this file |
nrf51_rtc.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/nrf51_rtc.cpp Wed Mar 18 09:35:02 2015 +0000 +++ b/nrf51_rtc.cpp Thu Apr 16 11:43:56 2015 +0000 @@ -2,13 +2,16 @@ #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; - rtc_previous = int (NRF_RTC1->COUNTER) / ticks_per_second; + time_base = rawtime; return 0; } @@ -20,10 +23,14 @@ // 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 - unsigned int rtc_now = (NRF_RTC1->COUNTER) / ticks_per_second; - unsigned int delta_seconds = ((rtc_now + counter_size_in_seconds) - rtc_previous) % counter_size_in_seconds; - time_base = time_base + (time_t) delta_seconds; - rtc_previous = rtc_now; + + 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; } @@ -32,13 +39,12 @@ rtc.time(); } -nrf51_rtc::nrf51_rtc() { +nrf51_rtc::nrf51_rtc() : + ticks_per_second(LFCLK_FREQUENCY / (NRF_RTC1->PRESCALER + 1)) +{ rtc_previous=0; time_base=0; - #define LFCLK_FREQUENCY 0x8000 - #define RTC_COUNTER_SIZE 0x1000000 - ticks_per_second = LFCLK_FREQUENCY / (NRF_RTC1->PRESCALER + 1); - counter_size_in_seconds = RTC_COUNTER_SIZE / ticks_per_second; + // 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)
--- a/nrf51_rtc.h Wed Mar 18 09:35:02 2015 +0000 +++ b/nrf51_rtc.h Thu Apr 16 11:43:56 2015 +0000 @@ -17,7 +17,7 @@ private: time_t time_base; unsigned int rtc_previous; - unsigned int ticks_per_second, counter_size_in_seconds; + const unsigned int ticks_per_second; }; extern nrf51_rtc rtc;