# RTC ## Overview The real-time clock \(RTC\) driver provides precise real time for the operating system \(OS\). If the OS is powered off, the RTC driver continues to keep track of the system time using an external battery. ## Available APIs **Table 1** APIs provided by the RTC driver

Capability

Function

Description

RTC handle

RtcOpen

Opens the RTC device to obtain its handle.

RtcClose

Releases a specified handle of the RTC device.

RTC time

RtcReadTime

Reads time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond.

RtcWriteTime

Writes time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond.

RTC alarm

RtcReadAlarm

Reads the RTC alarm time that was set last time.

RtcWriteAlarm

Writes the RTC alarm time based on the alarm index.

RtcRegisterAlarmCallback

Registers RtcAlarmCallback that will be invoked when an alarm is generated at the specified time.

RtcAlarmInterruptEnable

Enables or disables RTC alarm interrupts.

RTC configuration

RtcGetFreq

Reads the frequency of the external crystal oscillator connected to the RTC driver.

RtcSetFreq

Sets the frequency of the external crystal oscillator connected to the RTC driver.

RtcReset

Resets the RTC.

Custom register

RtcReadReg

Reads the configuration of a custom RTC register based on the register index.

RtcWriteReg

Writes the configuration of a custom RTC register based on the register index.

>![](../public_sys-resources/icon-note.gif) **NOTE**
>All functions provided in this document can be called only in kernel mode. ## Usage Guidelines ### How to Use During the OS startup, the HDF loads the RTC driver based on the configuration file. The RTC driver detects the RTC component and initializes the driver. The figure below illustrates how to use the APIs. **Figure 1** Process of using an RTC device ![](figures/using-rtc-process.png "process-of-using-an-rtc-device") ### Opening the RTC Device Handle After the RTC driver is loaded, you can use the API provided by the HDF and call APIs of the RTC driver. >![](../public_sys-resources/icon-note.gif) **NOTE**
>Currently, only one RTC device is supported in the OS. DevHandle RtcOpen\(void\); **Table 2** Description of RtcOpen

Parameter

Description

void

NA

Return Value

Description

handle

The operation is successful.

NULL

The operation failed.

``` DevHandle handle = NULL; /* Obtain the RTC device handle. */ handle = RtcOpen(); if (handle == NULL) { /* Process the error. */ } ``` ### Releasing the RTC Device Handle You can call **RtcClose()** function to release the RTC device handle, thereby releasing resources of the device. void RtcClose\(DevHandle handle\); **Table 3** Description of RtcClose

Parameter

Description

handle

RTC device handle.

``` /* Release the RTC device handle. */ RtcClose(handle); ``` ### Registering RtcAlarmCallback After the OS is started, call the following function to register **RtcAlarmCallback**, which will be invoked when an alarm is generated at the specified time: int32\_t RtcRegisterAlarmCallback\(DevHandle handle, enum RtcAlarmIndex alarmIndex, RtcAlarmCallback cb\); **Table 4** Description of RtcRegisterAlarmCallback

Parameter

Description

handle

RTC device handle.

alarmIndex

Alarm index.

cb

Callback that will be invoked when an alarm is generated at the specified time.

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

The following is an example of registering **RtcAlarmCallback** for processing alarm **RTC\_ALARM\_INDEX\_A**: ``` /* Register an RTC alarm callback. */ int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) { if (alarmIndex == RTC_ALARM_INDEX_A) { /* Process alarm A. */ } else if (alarmIndex == RTC_ALARM_INDEX_B) { /* Process alarm B. */ } else { /* Process the error. */ } return 0; } int32_t ret; /* Register RtcAlarmCallback for alarm A. */ ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); if (ret != 0) { /* Process the error. */ } ``` ### Performing RTC-related Operations - Reading RTC time Call the **RtcReadTime()** function to read time information from the RTC driver, including the year, month, the day of the week, day, hour, minute, second, and millisecond. int32\_t RtcReadTime\(DevHandle handle, struct RtcTime \*time\); **Table 5** Description of RtcReadTime

Parameter

Description

handle

RTC device handle.

time

Pointer to the time information read from the RTC driver. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

``` int32_t ret; struct RtcTime tm; /* Read time information from the RTC driver. */ ret = RtcReadTime(handle, &tm); if (ret != 0) { /* Process the error. */ } ``` - Setting RTC time Call the **RtcWriteTime()** function to set the RTC time. int32\_t RtcWriteTime\(DevHandle handle, struct RtcTime \*time\); **Table 6** Description of RtcWriteTime

Parameter

Description

handle

RTC device handle.

time

Pointer to the time information written into the RTC driver. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

>![](../public_sys-resources/icon-note.gif) **NOTE**
>The RTC start time is 1970/01/01 Thursday 00:00:00 \(UTC\). The maximum value of **year** must be set based on the requirements specified in the product manual of the in-use component. You do not need to configure the day of the week. ``` int32_t ret; struct RtcTime tm; /* Set the RTC time to UTC 2020/01/01 00:59:00 .000. */ tm.year = 2020; tm.month = 01; tm.day = 01; tm.hour= 00; tm.minute = 59; tm.second = 00; tm.millisecond = 0; /* Write the RTC time information. */ ret = RtcWriteTime(handle, &tm); if (ret != 0) { /* Process the error. */ } ``` - Reading the RTC alarm time Call the **RtcReadAlarm()** function to read the alarm time. int32\_t RtcReadAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); **Table 7** Description of RtcReadAlarm

Parameter

Description

handle

RTC device handle.

alarmIndex

Alarm index.

time

Pointer to the RTC alarm time information. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

``` int32_t ret; struct RtcTime alarmTime; /* Read the RTC alarm time information of alarm RTC_ALARM_INDEX_A. */ ret = RtcReadAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); if (ret != 0) { /* Process the error. */ } ``` - Setting RTC alarm time Call the **RtcWriteAlarm()** function to set the RTC alarm time based on the alarm index. int32\_t RtcWriteAlarm\(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime \*time\); **Table 8** Description of RtcWriteAlarm

Parameter

Description

handle

RTC device handle.

alarmIndex

Alarm index.

time

Pointer to the RTC alarm time information. The time information includes the year, month, the day of the week, day, hour, minute, second, and millisecond.

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

>![](../public_sys-resources/icon-note.gif) **NOTE**
>The RTC start time is 1970/01/01 Thursday 00:00:00 \(UTC\). The maximum value of **year** must be set based on the requirements specified in the product manual of the in-use component. You do not need to configure the day of the week. ``` int32_t ret; struct RtcTime alarmTime; /* Set the RTC alarm time to 2020/01/01 00:59:59 .000. */ alarmTime.year = 2020; alarmTime.month = 01; alarmTime.day = 01; alarmTime.hour = 00; alarmTime.minute = 59; alarmTime.second = 59; alarmTime.millisecond = 0; /* Set the alarm time of alarm RTC_ALARM_INDEX_A. */ ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); if (ret != 0) { /* Process the error. */ } ``` - Enabling or disabling alarm interrupts Before performing alarm operations, use the **RtcAlarmInterruptEnable()** function to enable alarm interrupts, so that **RtcAlarmCallback** will be called when the alarm is not generated upon a timeout. int32\_t RtcAlarmInterruptEnable\(DevHandle handle, enum RtcAlarmIndex alarmIndex, uint8\_t enable\); **Table 9** Description of RtcAlarmInterruptEnable

Parameter

Description

handle

RTC device handle.

alarmIndex

Alarm index.

enable

Whether to enable RTC alarm interrupts. The value 1 means to enable alarm interrupts and 0 means to disable alarm interrupts.

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

``` int32_t ret; /* Enable the RTC alarm interrupts. */ ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); if (ret != 0) { /* Process the error. */ } ``` - Reading RTC external frequency Call the **RtcGetFreq()** function to read the frequency of the external crystal oscillator connected to the RTC driver. int32\_t RtcGetFreq\(DevHandle handle, uint32\_t \*freq\); **Table 10** Description of RtcGetFreq

Parameter

Description

handle

RTC device handle.

freq

Pointer to the frequency to set for the external crystal oscillator, in Hz.

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

``` int32_t ret; uint32_t freq = 0; /* Read frequency of the external crystal oscillator connected to the RTC driver */ ret = RtcGetFreq(handle, &freq); if (ret != 0) { /* Process the error. */ } ``` - Setting the frequency of the external crystal oscillator connected to the RTC driver Call the **RtcSetFreq()** function to set the frequency of the external crystal oscillator connected to the RTC driver. int32\_t RtcSetFreq\(DevHandle handle, uint32\_t freq\); **Table 11** Description of RtcSetFreq

Parameter

Description

handle

RTC device handle.

freq

Frequency to set for the external crystal oscillator, in Hz

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

``` int32_t ret; uint32_t freq = 32768; /* 32768 Hz */ /* Set the frequency of the external crystal oscillator. Note that the frequency must be configured in accordance with the requirements specified in the product manual of the in-use component. */ ret = RtcSetFreq(handle, freq); if (ret != 0) { /* Process the error. */ } ``` - Resetting the RTC driver Call the **RtcReset()** function to perform a reset on the RTC driver \(after the reset, the registers are restored to the default values\). int32\_t RtcReset\(DevHandle handle\); **Table 12** Description of RtcReset

Parameter

Description

handle

RTC device handle.

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

``` int32_t ret; /* Reset the RTC driver. After the reset, the configuration registers are restored to the default values. */ ret = RtcReset(handle); if (ret != 0) { /* Process the error. */ } ``` - Reading the configuration of a custom RTC register Call the **RtcReadReg()** function to read the configuration of a custom RTC register based on the register index \(one index corresponds to one byte of the configuration value\): int32\_t RtcReadReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t \*value\); **Table 13** Description of RtcReadReg

Parameter

Description

handle

RTC device handle.

usrDefIndex

Index of the custom register

value

Pointer to the register value

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

``` int32_t ret; uint8_t usrDefIndex = 0; /* Define index 0 for the first custom register. */ uint8_t value = 0; /* Read the configuration of a custom RTC register based on the register index. One index corresponds to one byte of the configuration value. */ ret = RtcReadReg(handle, usrDefIndex, &value); if (ret != 0) { /* Process the error. */ } ``` - Setting the configuration of a custom RTC register Call the **RtcWriteReg()** function to configure a register based on the specified register index \(one index corresponds to one byte of the configuration value\). int32\_t RtcWriteReg\(DevHandle handle, uint8\_t usrDefIndex, uint8\_t value\); **Table 14** Description of RtcWriteReg

Parameter

Description

handle

RTC device handle.

usrDefIndex

Index of the custom register

value

Register value

Return Value

Description

0

The operation is successful.

Negative value

The operation failed.

``` int32_t ret; uint8_t usrDefIndex = 0; /* Define index 0 for the first custom register. */ uint8_t value = 0x10; /* Configure a register based on the specified register index. One index corresponds to one byte of the configuration value. */ ret = RtcWriteReg(handle, usrDefIndex, value); if (ret != 0) { /* Process the error. */ } ``` ## Usage Example This section describes the process of using RTC APIs: 1. During the OS startup, the HDF identifies the RTC component in the system. 2. The HDF initializes and creates the RTC device. 3. You can perform operations on the RTC device by calling different APIs. 4. Call the **RtcClose** function to release the device handle and device resources. Example: ``` #include "rtc_if.h" int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) { if (alarmIndex == RTC_ALARM_INDEX_A) { /* Process alarm A. */ printf("RTC Alarm A callback function\n\r"); } else if (alarmIndex == RTC_ALARM_INDEX_B) { /* Process alarm B. */ printf("RTC Alarm B callback function\n\r"); } else { /* Process the error. */ } return 0; } void RtcTestSample(void) { int32_t ret; struct RtcTime tm; struct RtcTime alarmTime; uint32_t freq; DevHandle handle = NULL; /* Obtain the RTC device handle. */ handle = RtcOpen(); if (handle == NULL) { /* Process the error. */ } /* Register RtcAlarmCallback for alarm A. */ ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); if (ret != 0) { /* Process the error. */ } /* Set the RTC external crystal frequency. Note that the frequency must be configured in accordance with the requirements specified in the product manual of the in-use component. */ freq = 32768; /* 32768 Hz */ ret = RtcSetFreq(handle, freq); if (ret != 0) { /* Process the error. */ } /* Enable the RTC alarm interrupts. */ ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); if (ret != 0) { /* Process the error. */ } /* Set the RTC time to 2020/01/01 00:00:10 .990. */ tm.year = 2020; tm.month = 01; tm.day = 01; tm.hour= 0; tm.minute = 0; tm.second = 10; tm.millisecond = 990; /* Write the RTC time information. */ ret = RtcWriteTime(handle, &tm); if (ret != 0) { /* Process the error. */ } /* Set the RTC alarm time to 2020/01/01 00:00:30 .100. */ alarmTime.year = 2020; alarmTime.month = 01; alarmTime.day = 01; alarmTime.hour = 0; alarmTime.minute = 0; alarmTime.second = 30; alarmTime.millisecond = 100; /* Set the alarm time information for RTC_ALARM_INDEX_A. When the specified time is reached, "RTC Alarm A callback function" is printed. */ ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); if (ret != 0) { /* Process the error. */ } /* Read the RTC real time. */ ret = RtcReadTime(handle, &tm); if (ret != 0) { /* Process the error. */ } sleep(5) printf("RTC read time:\n\r"); printf("year-month-date-weekday hour:minute:second .millisecond %04u-%02u-%02u-%u %02u:%02u:%02u .%03u", tm.year, tm.month, tm.day, tm.weekday, tm.hour, tm.minute, tm.second, tm.millisecond); /* Release the RTC device handle. */ RtcClose(handle); } ```