# RTC on Teensy 4.x

• 09-28-2020, 02:42 PM
cyrille
RTC on Teensy 4.x
Hello,

I was wondering if they was a RTC library for the Teensy4.x available?

I would like to be able, at least, to set the time/date, and get them... and hope that it stays "counting" when not in use...

Thanks,
Cyrille
• 09-28-2020, 03:34 PM
cyrille
Hello again.

I got this code from an older project on a different i.MX chip...
I made some small changes, but it does not yet work (does not compile, as I am missing the CCM module defintions)...
I am posting it here in case it helps...

Code:

```  static unsigned int const halNbDaysSince[] =  {  0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, };   static bool halDateLeap(uint32_t y) //return true if y is leap year   {     if (y%400==0) return true;     if (y%100==0) return false;     return ((y&3)==0);   }   static int32_t halDateDayIndexFromDateinternal(uint32_t d, uint32_t m, uint32_t y, bool leap)   {     y=y-1582;     uint32_t r= y*365;     r+=(y+2)/4; // every 4th year is leap     r-=(y+82)/100; // but every 100 is not     r+=(y+382)/400; // but every 400 is!     r+= halNbDaysSince[m-1]; // add months     if (leap && (m<=2)) r--; // adjust for leaps     r+= d-1; // add current day, 0 based, not 1...     if (r<273+14) return -1; // if before 15 october 1582, not a good date     return r;   }   static bool halDateFromDayIndex2(uint32_t a, uint32_t *Y, uint32_t *M, uint32_t *D)   {     uint32_t y, m;     if (a<273+14) return false; // begining of time     if (a>3074610) return false; // end of time 31 dec 9999     y= 1582;     if (a>=365) { y++; a-= 365; }     if (a>=365) { y++; a-= 365; } // up to 84, leap     if (a>=1461) { y+= 4; a-=1461; }     if (a>=1461) { y+= 4; a-=1461; }     if (a>=1461) { y+= 4; a-=1461; }     if (a>=1461) { y+= 4; a-=1461; } // up to 1600, leap...     while (a>=146097) { y+= 400; a-=146097; } // number of days in 400 years, leap years included     if (a>=36525) { y+= 100; a-=36525; } // number of days in 100 years with first year leap...     if (a>=36524) { y+= 100; a-=36524; } // number of days in 100 years     if (a>=36524) { y+= 100; a-=36524; } // number of days in 100 years     while (a>=(1461-(halDateLeap(y)?0:1))) { a-=(1461-(halDateLeap(y)?0:1)); y+= 4; } // number of days in 4 years.. handle case where first year is not leap!     while (a>=(365+(halDateLeap(y)?1:0))) { a-= (365+(halDateLeap(y)?1:0)); y++; }     m=11;     while ((uint32_t)a<(halNbDaysSince[m]+((m>=2)&&(halDateLeap(y)?1:0)))) m--;     a= a - halNbDaysSince[m] - ((m>=2)&&(halDateLeap(y)?1:0));     a++; // days are 1 based, not 0...     m++; // same for months     if (Y!=NULL) *Y= y; if (M!=NULL) *M= m; if (D!=NULL) *D= a;     return true;   } static uint32_t volatile * const SNVS= (uint32_t volatile *)0x400D4000; static uint32_t volatile * const HPCOMR= SNVS+(0x4/4); static uint32_t volatile * const HPCR= SNVS+(0x8/4); static uint32_t volatile * const HPSRTCMR= SNVS+(0x24/4); static uint32_t volatile * const HPSRTCLR= SNVS+(0x28/4);   static uint64_t RTC_GetNow()   {     // get timer. since it is spread on 2 registers. one 32 bit one and one 15 bit ones, need to do 2 reads and make sure that they match     uint64_t t1= (((uint64_t)*HPSRTCMR)<<32) + *HPSRTCLR; // Get "now"     while (true) { uint64_t t2= (((uint64_t)*HPSRTCMR)<<32) + *HPSRTCLR; if (t1==t2) return t1; t1= t2; }   } void getDateTime(uint32_t *year, uint32_t *month, uint32_t *day, uint32_t *hour, uint32_t *min, uint32_t *sec, uint32_t *ms) {   uint64_t t1= RTC_GetNow();   // 15 bit per seconds... use lower 15 bits for ms if needed   if (ms!=NULL) *ms= (((uint32_t)t1 & 0x7fff) * 1000) >> 15; // get the number of ms if needed   uint32_t tquot= (uint32_t)(t1>>15)/60; if (sec!=NULL) *sec= (uint32_t)(t1>>15)-tquot*60; // div mod nb seconds by 60 to separate seconds from the rest   uint32_t tquot2= tquot/60; if (min!=NULL) *min= tquot-tquot2*60;              // div mod rest by 60 to get minutes and the rest   tquot= tquot2/24; if (hour!=NULL) *hour= tquot2-tquot*24;                // div mod rest by 24 to get hours and days since jan 1 2000   // 152671 days from jan 1 1582 to jan 1 2000 (uncorrected for calendar change), which is what is used by DateFromDayIndex2 in napier   halDateFromDayIndex2(152671+tquot, year, month, day); } void setDateTime(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec) {   uint32_t y2, m2, d2, h2, M2, s2;   getDateTime(&y2, &m2, &d2, &h2, &M2, &s2, NULL);   if (year==-1) year= y2; if (month==-1) month= m2; if (day==-1) day= d2; if (hour==-1) hour= h2; if (min==-1) min= M2; if (sec==-1) sec= s2;   uint64_t res= (halDateDayIndexFromDateinternal(day, month, year, halDateLeap(year))-152671)*24*60*60;   res+= 60*60*hour + 60*min + sec;   res<<=15;   *HPCR&= ~1; while ((*HPCR&1)!=0);              // stop RTC   *HPSRTCLR= (uint32_t)res; *HPSRTCMR= (uint32_t)(res>>32); // program registers   *HPCR|= 1; while ((*HPCR&1)==0);                // re-enable RTC } void RTC_boot() {     CCM->CCGR5 |= CCM_CCGR5_CG14(3);  //SNVS_HP_CLK_ENABLE     CCM->CCGR5 |= CCM_CCGR5_CG15(3);  //SNVS_LP_CLK_ENABLE     *HPCOMR = (1U<<31); // enable all can read registers //    SNVS->HPCR= SNVS_HPCR_BTN_CONFIG(3) | SNVS_HPCR_BTN_MASK_MASK; // ON button active on falling edge and ON button irq enabled //    while ((SNVS->HPCR&SNVS_HPCR_BTN_MASK_MASK)==0); // wait until validated     //SNVS->LPCR= (2<<20) | (3<<16) | (1<<5) | 1;  // Set ON_TIME delay, BTN debounce, dumb_pmic, clock enabled     *HPCR|= 1;     while ((*HPCR&1)==0); // make sure clock is on! }```
• 09-28-2020, 05:04 PM
KurtE
Sorry, I have not played around very much with RTC...

But if I were going to, I would look at the stuff built into the core:

Both Teensy 3.x and 4.x have a class built in:
Code:

```class teensy3_clock_class { public:         static unsigned long get(void) __attribute__((always_inline)) { return rtc_get(); }         static void set(unsigned long t) __attribute__((always_inline)) { rtc_set(t); }         static void compensate(int adj) __attribute__((always_inline)) { rtc_compensate(adj); } }; extern teensy3_clock_class Teensy3Clock;```
And also the time library and at the example: examples->Time->TeensyTime3
• 09-28-2020, 05:55 PM
cyrille
Hello,

Thanks for the info.
Where do you actually find that information? Is there a list of all the classes? or a "class explorer" of some type?

Cyrille
• 09-28-2020, 06:04 PM
KurtE
Part of it by playing with a lot of this stuff over several years.

And then an open SublimeText 3 (editor) window open on the (<arduino install>/hardware/teensy/avr) directory and doing a global Search command for something like RTC and see where I get hits...