4. DA14531 Real Time Clock (RTC)

The DA14531 contains a Real Time Clock (RTC) featuring a full clock and calendar and an alarm function. Alarms can be generated in two ways, a one-time alarm or a recurring alarm. In addition to alarms, the RTC can detect when a particular event occurs. Each field of the calendar and time counters can generate an event when it rolls over. For example, an event can be generated every new month, new week, new day, new half day (12-hour mode), new minute, or new second. Both alarms and events can generate an interrupt and these can be set, enabled, disabled, or masked at any time.

Note

You must have created a modified version of the empty_peripheral_template example project, as described in the Initial Project chapter before proceeding!

4.1. Using the RTC Peripheral Driver

The following section provides step-by-step instructions showing how to update the modified empty_peripheral_template example project you created in the Initial Project chapter to use the RTC via the peripheral driver provided with SDK6.

4.1.1. Adding the RTC Driver

Before it can be used the RTC driver must be added to the empty_peripheral_template example project. This can be done by right-clicking the sdk_driver folder in the Project explorer window and then selecting the “Add Existing file to Group ‘sdk_driver’..” option:

_images/rtc_driver_file.png

Figure 6 Adding RTC driver to the example project

Then navigate to the location of the RTC driver file (../../../../../sdk/platform/driver/rtc/rtc.c) and add it to the project.

4.1.2. Initializing the RTC

The first step when initializing the RTC is to configure and enable the clock and set the mode. The RTC is clocked by the internal LP clock and this can be generated from either the internal RCX oscillator or an external 32kHz crystal. The LP clock source is selected via the CFG_LP_CLK macro that can be found in the da1458x_config_advanced.h file. We will leave this as the default setting, which is to use the internal RCX oscillator.

In order to use the RTC driver functions we need to add the appropriate include files into user_empty_peripheral_template.c

#include "rtc.h"
#include "arch_system.h"

To configure the clock and set the date and time add the following to the user_on_init() function:

/* Power domain in which the RTC resides is disabled by default and so
   needs to be enabled before we can use it.  */
SetBits16(PMU_CTRL_REG, TIM_SLEEP, 0);
while ((GetWord32(SYS_STAT_REG) & TIM_IS_UP) != TIM_IS_UP);

/* Put RTC into known state */
rtc_reset();

/* Configure the RTC 100Hz clock, based on the LP clock frequency */
if (arch_clk_is_RCX20()) {
    extern uint32_t rcx_freq;
    /* Use the calibrated RCX frequency */
    rtc_clk_config(RTC_DIV_DENOM_1000, rcx_freq);
} else {
    rtc_clk_config(RTC_DIV_DENOM_1024, 32768);
}
rtc_clock_enable();

/* Default RTC configuration */
static const rtc_config_t cfg_rtc = {
    .hour_clk_mode = RTC_HOUR_MODE_24H,
    .keep_rtc = true,
};

/* Initialize RTC, it will be started when the date and time are set */
rtc_init(&cfg_rtc);

rtc_time_t time;
rtc_calendar_t clndr;
rtc_status_code_t status;

time.hour = 0;
time.minute = 0;
time.sec = 0;
time.hsec = 0;
time.hour_mode = RTC_HOUR_MODE_24H;
clndr.year = 1970;
clndr.month = 1;
clndr.mday = 1;
clndr.wday = 1;

/* Setting the time/date will also start the RTC if it was not running */
status = rtc_set_time_clndr(&time, &clndr);

arch_printf("\n\rInitialized RTC: 0x%02X", status);

4.1.3. Reading the RTC

We can now confirm the RTC is running by adding the following code to the user_on_connection() function:

rtc_time_t time;
rtc_calendar_t clndr;

/* Read time and date from on-chip RTC */
rtc_get_time_clndr(&time, &clndr);

arch_printf("\n\r%s", __FUNCTION__);
arch_printf("\n\rTime - %02d:%02d:%02d", time.hour, time.minute, time.sec);
arch_printf("\n\rDate - %02d-%02d-%04d", clndr.month, clndr.mday, clndr.year);

This will result in the current time and data from the RTC being output via the serial debug port whenever a central is connected.

To test first configure your Terminal Emulator as follows:

  • Baud Rate: 115200

  • Data: 8 bits

  • Parity: None

  • Stop Bits: 1

  • Flow Control: None

Then, build the project and load it onto target.

Finally, using your favourite Bluetooth Explorer tool, connect to the Development Kit board (the device name is DIALOG-TMPL) and you should see something like the following displayed by your Terminal Emulator:

_images/rtc_debug_output.png

Figure 7 Serial debug output on connection

When you then disconnect and re-connect again you should see that the time has incremented.

4.1.4. Events & Alarms

The RTC can generate an interrupt that will wake the DA14531 from sleep mode. This interrupt can be generated as a result of an event or an alarm:

  • Events: Generated when a time or date field rolls over.

  • Alarms: Generated when a certain time and/or date is reached.

To generate an interrupt (based on an event) that wakes the DA14531 every 1 minute add the following code to the user_on_init() function, just after the function call that sets the time and date (rtc_set_time_clndr):

/* Register callback and enable interrupt */
rtc_register_intr(rtc_interrupt_cb, RTC_EVENT_MIN);

Then create a callback function that will be executed when the interrupt occurs (place it just before the user_on_init function):

static void rtc_interrupt_cb(uint8_t event)
{
    arch_printf("\n\r%s - Event: 0x%02X", __FUNCTION__, event);
}

This will result in the following message being output via the serial debug port every 1 minute:

_images/event_output.png

Figure 8 Serial debug output on RTC event