This program is an example of an attempt at a Real Time Clock on the nRF51-DK.

Dependencies:   mbed nrf51_rtc

main.cpp

Committer:
fxschumacher
Date:
2015-02-08
Revision:
1:c1f06d0a5e11
Parent:
0:8a9f15c4effd

File content as of revision 1:c1f06d0a5e11:

/*
This example code shows one way of creating a real time clock for the nRF51 without interfering with the mbed library functions

Two methods are created to replace the similarly named C routines:  rtc.time and rtc.set_time.
If the rtc.time method isn't called frequently (< 512 seconds between calls), a ticker (from the mbed library) is required 
to keep the time updated.

In this example, LED2 toggles and the time is printed when button1 is pushed.  LED1 will toggle when the time is periodically updated.

references:
  -- see NRF_RTC_Type in nrf51.h 
  (e.g.:  http://developer.mbed.org/users/mbed_official/code/mbed-src/file/12a9a5f8fea0/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/nrf51.h)
  -- see "nRF51 Series Reference Manual" chapter on Real Time Counter (chapter 19 in V3.0)
Note:  RTC2 does not exist, despite what the nrf51 reference manual (V3.0) claims.  The other RTCs (0/1) are used by various other libraries,
so you can read, but don't write! 

*/

#include "mbed.h"
#include "nrf51_rtc.h"

// used for the example only, not required for rtc use
DigitalOut rtc_update_led(LED1); // toggle when update_rtc is called
DigitalOut button_push_led(LED2); // toggle when button1 is pushed
DigitalIn  button1(BUTTON1);  // used to trigger the time report
InterruptIn button1Press(BUTTON1);
Serial pc(USBTX,USBRX);

time_t example_time() {
    // set an intial time
    //  ...not really necessary for this example, but it beats setting it to 0 or some non-obvious large integer (# of seconds since 1/1/1970)
    time_t rawtime=0;

    struct tm * init_timeinfo;

    // initialize time
    init_timeinfo = localtime(&rawtime); // note:  must initialize the struct with this before trying to set components
                                         // ...else code goes into the weeds!!
    init_timeinfo->tm_sec = 0;
    init_timeinfo->tm_min = 10;
    init_timeinfo->tm_hour = 17;
    init_timeinfo->tm_mon = 1;
    init_timeinfo->tm_mday = 7;
    init_timeinfo->tm_year = 2015 - 1900;        

    char date[24];
    strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",init_timeinfo);
    pc.printf("Initial time set is %s.\r\n",date);
    
    // compute the proper value for time in time_t type
    rawtime = mktime(init_timeinfo);
    return rawtime;
}
void print_time() {
    // called when a button is pushed, this prints the current time to the USB-connected console
    button_push_led = !button_push_led; 
    
    time_t rawtime=rtc.time();
    
    // massage the time into a human-friendly format for printing
    struct tm * timeinfo;
    timeinfo = localtime(&rawtime);
    char date[24];
    strftime(date,sizeof(date),"%H:%M:%S on %m/%d/%G",timeinfo);
    pc.printf("The current time is %s.\r\n",date);
}

// (probably) required for rtc use
void update_rtc() {
    // for use as interrupt routine, to insure that RTC is updated periodically
    //  ...if rtc is not read before the underlying counter rolls over (typically 512 seconds), the RTC value will be wrong
    //  ...ideally this would be done as part of the nrf51_rtc method, but I couldn't get it to behave (see nrf51_rtc.cpp for details)
    rtc.time();
    rtc_update_led = !rtc_update_led;
}


int main(void)
{
    rtc_update_led=0;
    button_push_led=0;
    
    // user selectable, any time < 512 seconds is OK
    #define PERIODIC_UPDATE 1
    Ticker rtc_ticker;
    rtc_ticker.attach(&update_rtc, PERIODIC_UPDATE); // update the time regularly
    
    time_t initial_time = example_time();
    rtc.set_time(initial_time);
    
    button1Press.fall(&print_time);  // when button1 is pressed, this calls rtc.time() and prints it
     
    while (true) {
        sleep();
    }
}