The MCA implements a real-time clock (RTC) in its firmware. On the ConnectCore 8X the internal CPU RTC is disabled because the MCA implementation handles power consumption more efficiently.

To keep the date during power-off you must connect a coin cell battery to the board.

Kernel configuration

You can manage the MCA RTC driver support through the following kernel configuration option:

  • Digi ConnectCore SOMs Micro Controller Assist RTC (CONFIG_RTC_DRV_MCA)

This option is enabled as built-in on the default ConnectCore 8X kernel configuration file.

Kernel driver

The MCA GPIO driver is located at:

File Description

drivers/rtc/rtc-mca.c

MCA RTC driver

Device tree bindings and customization

The MCA RTC device tree binding is documented at Documentation/devicetree/bindings/rtc/digi,mca-rtc.txt.

RTC inside the MCA

ConnectCore 8X device tree
mca_cc8x: mca@63 {

	...

	rtc {
		compatible = "digi,mca-cc8x-rtc";
	};
};

Using the RTC

The MCA RTC is accessible via the file descriptor /dev/rtc0. The /dev/rtc device is a symbolic link to /dev/rtc0.

System time in Linux

On boot-up, Linux sets the system time from the data kept on the RTC. If a more recent time-stamp exists in /etc/timestamp then it uses that time-stamp instead. The file /etc/timestamp is initially sourced with the image build timestamp and updated with the system time on a clean reboot/poweroff process.

When connected to the Internet, Digi Embedded Yocto uses a NTP (network time protocol) daemon to set the RTC time and keep the system time up to date.

Setting a date

To set the system time, use the date command:

~# date -s "2017-02-23 11:30:00"

To write the system time to the RTC, use the hwclock command:

~# hwclock -w

Example application

Digi Embedded Yocto provides a basic RTC test application. Build the package dey-examples-rtc in your Yocto project to install the test application rtc_test.

The RTC test application allows you to:

  • read the current time from the RTC

  • set it using the system time

  • read, set, and test the alarm interrupt

To display the application syntax, run:

~# rtc_test -h

Test the alarm interrupt with the specified seconds:

~# rtc_test -e -s 20

In this case, the test sets the RTC alarm to 20 seconds from the current time and then waits for the alarm interrupt to occur.

Periodic and 1 Hz interrupts

The standard RTC Linux API provides the following IOCTLs to use periodic and 1 Hz interrupts:

  • RTC_UIE_ON/RTC_UIE_OFF: Enable or disable the interrupt on every clock update.

  • RTC_PIE_ON/RTC_PIE_OFF: Enable or disable the periodic interrupt.

  • RTC_IRQP_READ/RTC_IRQP_SET: Read and set the frequency for periodic interrupts.

However, Linux is not using RTC-specific resources of the MCA for handling these IOCTLs and handles them using SOC resources.

Digi provides sibling IOCTLs that make full use of MCA RTC features. To use them, add the following definitions to your application:

1 2 3 4 5 6 7 8
// Custom Digi RTC IOCTL implementation using MCA #define RTC_IOCTL_DIGI 0x100 #define RTC_MCA_UIE_ON (RTC_IOCTL_DIGI + RTC_UIE_ON) #define RTC_MCA_UIE_OFF (RTC_IOCTL_DIGI + RTC_UIE_OFF) #define RTC_MCA_PIE_ON (RTC_IOCTL_DIGI + RTC_PIE_ON) #define RTC_MCA_PIE_OFF (RTC_IOCTL_DIGI + RTC_PIE_OFF) #define RTC_MCA_IRQP_READ (RTC_IOCTL_DIGI + RTC_IRQP_READ) #define RTC_MCA_IRQP_SET (RTC_IOCTL_DIGI + RTC_IRQP_SET)

Example application for periodic and 1 Hz interrupts

The example application supports different options to test periodic and 1 Hz interrupts:

-p : Test the standard periodic interrupts (uses timers, doesn't wake from low power)
-u : Test the standard 1 Hz interrupt (uses RTC ALARM)
-v : Test MCA periodic interrupts (uses RTC PERIODIC_IRQ)
-w : Test MCA 1 Hz interrupt (uses RTC 1HZ)

To check the MCA IRQs that trigger during the test, run:

~# cat /proc/interrupts | grep RTC
222:         10  mca-cc8x-irq   0 Level     RTC ALARM
223:         10  mca-cc8x-irq   1 Level     RTC 1HZ
224:        120  mca-cc8x-irq   2 Level     RTC PERIODIC_IRQ

GPIO for periodic and 1 Hz interrupts

To toggle an MCA GPIO when the periodic or 1 Hz interrupt triggers, use the following command (noting that this particular example is for MCA_IO7):

~# echo 7 > /sys/devices/platform/5a800000.i2c/i2c-0/0-0063/mca-cc8x-rtc/rtc_irq_pin
~# echo enabled > /sys/devices/platform/5a800000.i2c/i2c-0/0-0063/mca-cc8x-rtc/rtc_irq_pin_enable

Time compensation

The MCA’s RTC increments every time the internal 32.768 kHz signal goes through 32768 cycles. However, factors such as temperature changes or slight imperfections in the crystal that generates the signal may cause the RTC to be faster or slower than it should be. When the system has been powered on for a long period and the time can’t be updated via NTP, there may be large time differences between the RTC and the actual time.

To solve this, the RTC has a time compensation system that can adjust the number of cycles needed to increment the RTC counter.

How to configure the RTC time compensation

  1. Accurately measure the 32 kHz signal of your ConnectCore 8X SOM’s MCA. For example, although a measurement of 32.76683 kHz seems slight, after 30 days of operation at this value, the MCA RTC will be off by more than 90 seconds. Note that the measured frequency might fluctuate through time depending on the SOM’s temperature.

  2. Use the mca_config_tool to set the measured frequency in Hertz. The tool will calculate the optimal time compensation parameter values for that frequency and write them to the MCA:

~# mca_config_tool --rtc_time_comp=32766.83
Configuration saved.

See MCA configuration tool for additional information on how to configure the time compensation system.

Because the value ranges for the time compensation parameters are limited, it’s not always possible to find exact values for a given frequency. In these cases, the mca_config_tool will round the frequency to the nearest representable value and print a warning:

~# mca_config_tool --rtc_time_comp=32767.571
WARNING: Not enough precision to configure RTC compensation for 32767.571000 Hz.
Rounding down to 32767.570866 Hz.
Configuration saved.