Jump to content
spirilis

[Energia Library] Wolverine RTC_B library

Recommended Posts

Inspired by @@B@tto 's RTC_A library located here -- http://forum.43oh.com/topic/5421-energia-library-rtc-a/ -- I wanted an RTC_B library for doing work with my Wolverine LaunchPad.

 

So after realizing his library wouldn't compile on the Wolverine correctly, I looked into the user's guide and realized the RTC_B has quite a few changes over the RTC_A, so it was better to just start from scratch.  So I made a library that I think does the job quite well.

 

See https://github.com/spirilis/RTC_B

 

The documentation is drafted directly into the README.md file shown on the main page.

The library contains 4 examples to showcase its features.

 

One feature that is noteworthy here is the .save() and .restore() feature--the library automatically allocates a 9-byte FRAM buffer in the ".text" section which can store a copy of the current date/time info when the user runs rtc.save() in the sketch, and upon reset the sketch can be programmed to run rtc.restore() -- this function returns "true" if the FRAM segment was initialized with legitimate date/time data, or "false" if it was not (e.g. after initially uploading a sketch).  The time buffer is only 8 bytes but the 9th byte holds a magic cookie which indicates whether the buffer has date/time info stored or not.

 

But in addition to all that, the library supports string output with rtc.getTimeString() ... this doesn't use the String class, but rather stores its data in a char * buffer supplied by you.  The string output is configurable too, with the rtc.setTimeStringFormat() function.

 

Anyway my initial requirement that prompted the creation of this library is an in-FRAM table for storing Lightning Sensor strike data from the AS3935 Franklin Lightning Sensor which I received recently from TAUTIC at Tindie.com.  I hope this library proves useful to other Wolverine users and as always if there are any bugs or questions, post in here and let me know!

 

Share this post


Link to post
Share on other sites

One feature I do intend to add soon is support for the trim adjustment--calibrating the RTC with its calibration output pin and storing a constant that can be added to .begin() to precalibrate the RTC in sketches.

 

Sent from my Galaxy Note II with Tapatalk 4

Share this post


Link to post
Share on other sites

Very cool! I'll definitely try this out.

I've been kludging my way through the FR5969 RTC (and apparently looking at the wrong datasheet section while doing it, oops, maybe that's why I couldn't make the alarm function work...) and found it to be quite nice.

 

Having a library surrounding it would definitely make things easier, and having read the readme included with said library it looks nice and powerful as well.

 

Thank you!

Share this post


Link to post
Share on other sites

Very cool! I'll definitely try this out.

I've been kludging my way through the FR5969 RTC (and apparently looking at the wrong datasheet section while doing it, oops, maybe that's why I couldn't make the alarm function work...) and found it to be quite nice.

 

Having a library surrounding it would definitely make things easier, and having read the readme included with said library it looks nice and powerful as well.

 

Thank you!

After reading through the datasheet a few times it's really not that complex, HOWEVER BE AWARE there's a quirk in the documentation that TI does spell out on the main register manifest (e.g. page 477, the "Table 19-1. RTC_B Registers") but you'd miss if you weren't paying close attention.

 

The main RTCCTL registers (of which 4 are mentioned - RTCCTL0, RTCCTL1, RTCCTL2, RTCCTL3) are actually comprised of two word-width registers, RTCCTL01 and RTCCTL23.  The problem is the register bit names -- e.g. "RTCHOLD" and "RTCRDY" in RTCCTL1 - resolve to word-size numbers:

/* RTCCTL01 Control Bits */
#define RTCBCD              (0x8000)     /* RTC BCD  0:Binary / 1:BCD */
#define RTCHOLD             (0x4000)     /* RTC Hold */
//#define RESERVED            (0x2000)     /* RESERVED */
#define RTCRDY              (0x1000)     /* RTC Ready */
//#define RESERVED            (0x0800)     /* RESERVED */
//#define RESERVED            (0x0400)     /* RESERVED */
#define RTCTEV1             (0x0200)     /* RTC Time Event 1 */
#define RTCTEV0             (0x0100)     /* RTC Time Event 0 */
#define RTCOFIE             (0x0080)     /* RTC 32kHz cyrstal oscillator fault interrupt enable */
#define RTCTEVIE            (0x0040)     /* RTC Time Event Interrupt Enable Flag */
#define RTCAIE              (0x0020)     /* RTC Alarm Interrupt Enable Flag */
#define RTCRDYIE            (0x0010)     /* RTC Ready Interrupt Enable Flag */
#define RTCOFIFG            (0x0008)     /* RTC 32kHz cyrstal oscillator fault interrupt flag */
#define RTCTEVIFG           (0x0004)     /* RTC Time Event Interrupt Flag */
#define RTCAIFG             (0x0002)     /* RTC Alarm Interrupt Flag */
#define RTCRDYIFG           (0x0001)     /* RTC Ready Interrupt Flag */

Notice how RTCRDY is a 16-bit number, 0x1000.  If you want to use the RTCRDY constant in your code you'd have to use it against "RTCCTL01", not "RTCCTL1".  My initial release (after the long binge coding session writing most of the functions) was doing:

RTCCTL1 |= RTCHOLD;

and the RTCRDY semaphore function did:

while (!(RTCCTL1 & RTCRDY)) ;

 

Which hung, indefinitely, because RTCCTL1 is an 8-bit accessor to the upper byte of RTCCTL01 while RTCRDY is the 16-bit word-at-once comparison bitmask.  I had to change those to:

 

RTCCTL1 |= RTCHOLD_H;

and

while (!(RTCCTL1 & RTCRDY_H)) ;

 

and then it worked.  Just something to bring to your attention.  The main RTC date/time configuration registers are all 8-bits though I believe.

Share this post


Link to post
Share on other sites

That explains something at least.

I'm hoping my alarm issues were due to subtle differences between A and B, as I thought I understood it based on the datasheet.

 

I'm hoping I can steal some time to play with this library today.

Share this post


Link to post
Share on other sites

Do you think @@spirilis that the RTC library should also provide an automatic dow calculation?

 

I know the hardware doesn't set it, but I've never seen a clock where you had to define your dow, you cold potentially mess up the functionality if you set it wrong.

 

Have you looked at any automatic dow calculations? The only one I've every used was a lookup table from wikipedia, but there are certainly better ways. http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week

Share this post


Link to post
Share on other sites

Do you think @@spirilis that the RTC library should also provide an automatic dow calculation?

 

I know the hardware doesn't set it, but I've never seen a clock where you had to define your dow, you cold potentially mess up the functionality if you set it wrong.

 

Have you looked at any automatic dow calculations? The only one I've every used was a lookup table from wikipedia, but there are certainly better ways. http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week

Nope, that might not be a bad idea though if it's simple enough...

Share this post


Link to post
Share on other sites

Library update- rtc.begin() now returns true/false if it was successful; the reason it may be unsuccessful is that LFXT1 is faulted.  Discovered that this past weekend with my Wolverine Lightning Sensor gadget... condensation overnight (even sitting inside a cabinet at the TI booth) wrecked all kinds of havoc with the Wolverine board.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×