diff --git a/docs/api.md b/docs/api.md index 8b025a5..29424d4 100644 --- a/docs/api.md +++ b/docs/api.md @@ -411,3 +411,17 @@ rtc.standbyMode() #### Parameters None + +### `setFrequencyCorrection()` + +Set the RTC frequency correction value. A positive value reduces the frequency, a negative value will increase the frequency. + +#### Syntax + +``` arduino +rtc.setFrequencyCorrection(int8_t correction) +``` + +#### Parameters + +- correction: the number of counts to be increased or decreasd periodically by the RTC frequency correction module. diff --git a/keywords.txt b/keywords.txt index 547d5dd..5f23b62 100644 --- a/keywords.txt +++ b/keywords.txt @@ -54,6 +54,8 @@ disableAlarm KEYWORD2 standbyMode KEYWORD2 +setFrequencyCorrection KEYWORD2 + ####################################### # Constants (LITERAL1) ####################################### diff --git a/src/RTCZero.cpp b/src/RTCZero.cpp index 593a8bb..d6c0724 100644 --- a/src/RTCZero.cpp +++ b/src/RTCZero.cpp @@ -464,6 +464,34 @@ void RTCZero::configureClock() { ; } +/* + * From: SAM D21 Family Datasheet - Chapter 19.6.9.2 + * ============================================================================ + * Correction[ppm] = (FREQCORR.VALUE / 4096 * 240) * 10^6 ppm + * + * FREQCORR.VALUE = (correction[ppm] * 4096 * 240) / 10^6 = correction * 4096 * 240 + * + * Example: + * Correction = 1s / 24h = 1s / 86400s = 1/86400 + * FREQCORR.VALUE = 1/86400 * 4096 * 240 = 11 + */ + +void RTCZero::setFrequencyCorrection(int8_t correction) +{ + if (correction == 0 || correction == -128) { + return; + } + + uint8_t sign = (correction & 0x80); + + if (correction < 0) { + correction *= -1; + } + + while(RTC->MODE2.STATUS.bit.SYNCBUSY); + RTC->MODE2.FREQCORR.reg = sign | correction; +} + /* * Private Utility Functions */ diff --git a/src/RTCZero.h b/src/RTCZero.h index e0bfb64..a6d5411 100644 --- a/src/RTCZero.h +++ b/src/RTCZero.h @@ -22,6 +22,8 @@ #include "Arduino.h" +#define RTCZERO_FREQCORR(_CORR_) (_CORR_ * 240 * 4096) + typedef void(*voidFuncPtr)(void); class RTCZero { @@ -88,6 +90,8 @@ class RTCZero { void setAlarmMonth(uint8_t month); void setAlarmYear(uint8_t year); void setAlarmDate(uint8_t day, uint8_t month, uint8_t year); + + void setFrequencyCorrection(int8_t correction); /* Epoch Functions */