1# RTC 2 3 4## Overview 5 6The real-time clock (RTC) provides precise real time for the operating system (OS) and scheduled alarming function. When the device is powered off, the RTC can accurately keep track of the system time using an auxiliary battery. The RTC regulates time with the use of a crystal oscillator. 7 8 9## Available APIs 10 11 **Table 1** RTC APIs 12 13| Category| Description| 14| -------- | -------- | 15| RTC handle| **RtcOpen**: opens the RTC device to obtain its handle.<br>**RtcClose**: closes the RTC device handle.| 16| RTC time| **RtcReadTime**: reads the RTC time information, which includes the year, month, day, day of week, hour, minute, second, and millisecond.<br>**RtcWriteTime**: writes the RTC time, including the year, month, day, day of week, hour, minute, second, and millisecond.| 17| RTC alarm| **RtcReadAlarm**: reads the RTC alarm time.<br>**RtcWriteAlarm**: writes the RTC alarm time.<br>**RtcRegisterAlarmCallback**: registers a callback to be invoked when an alarm is not generated at the specified time.<br>**RtcAlarmInterruptEnable**: enables or disables interrupts for an RTC alarm.| 18| RTC configuration| **RtcGetFreq**: obtains the frequency of the external crystal oscillator connected to the RTC driver.<br>**RtcSetFreq**: sets the frequency of the external crystal oscillator connected to the RTC driver.<br>**RtcReset**: resets the RTC.| 19| Custom register| **RtcReadReg**: reads a custom register.<br>**RtcWriteReg**: writes a custom register.| 20 21> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> 22> All APIs described in this document can be called only in kernel mode. 23 24 25## Usage Guidelines 26 27 28### How to Use 29 30During the OS startup, the HDF loads the RTC driver based on the configuration file. The RTC driver detects the RTC device and initializes the driver. 31 32The figure below illustrates the general development process of an RTC device. 33 34 **Figure 1** Using the RTC APIs 35 36 ![image](figures/using-RTC-process.png "Using RTC APIs") 37 38 39### Opening the RTC Device Handle 40 41After the RTC driver is loaded, the API provided by the HDF is called to invoke the APIs of the RTC driver. 42 43> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> 44> Only one RTC device is supported in the OS. 45 46```c 47DevHandle RtcOpen(void); 48``` 49 50 **Table 2** Description of RtcOpen 51 52| **Parameter**| **Description**| 53| -------- | -------- | 54| void | NA | 55| **Return Value**| **Description**| 56| handle | The operation is successful.| 57| NULL | The operation failed.| 58 59 60``` 61DevHandle handle = NULL; 62 63/* Open the RTC device handle. */ 64handle = RtcOpen(); 65if (handle == NULL) { 66 /* Error handling. */ 67} 68``` 69 70 71### Closing the RTC Device Handle 72 73Call **RtcClose()** to release the resources used by the RTC device. 74 75```c 76void RtcClose(DevHandle handle); 77``` 78 79 **Table 3** Description of RtcClose 80 81| **Parameter**| **Description**| 82| -------- | -------- | 83| handle | RTC device handle to close.| 84 85 86``` 87/* Close the RTC device handle. */ 88RtcClose(handle); 89``` 90 91 92### Registering an Alarm Callback 93 94Call **RtcRegisterAlarmCallback** to register a callback, which will be invoked when the specified alarm is not generated at the specified time. 95 96```c 97int32_t RtcRegisterAlarmCallback(DevHandle handle, enum RtcAlarmIndex alarmIndex, RtcAlarmCallback cb); 98``` 99 100 **Table 4** Description of RtcRegisterAlarmCallback 101 102| **Parameter**| **Description**| 103| -------- | -------- | 104| handle | RTC device handle.| 105| alarmIndex | Alarm index.| 106| cb | Callback to be invoked when the alarm is not generated at the specified time.| 107| **Return Value**| **Description**| 108| 0 | The operation is successful.| 109| Negative value| The operation failed.| 110 111 The following is an example of registering a callback for processing alarm RTC_ALARM_INDEX_A: 112 113``` 114/* Register a callback for alarm RTC_ALARM_INDEX_A. */ 115int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) 116{ 117 if (alarmIndex == RTC_ALARM_INDEX_A) { 118 /* Processing of alarm A. */ 119 } else if (alarmIndex == RTC_ALARM_INDEX_B) { 120 /* Processing of alarm B. */ 121 } else { 122 /* Error handling. */ 123 } 124 return 0; 125} 126int32_t ret; 127/* Register a callback to be invoked when alarm A is not generated at the specified time. */ 128ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); 129if (ret != 0) { 130 /* Error handling. */ 131} 132``` 133 134 135### Performing RTC-related Operations 136 137- Reading the RTC time 138 139Call **RtcReadTime()** to obtain the RTC time, which includes the year, month, day, day of week, hour, minute, second, and millisecond. 140 141```c 142int32_t RtcReadTime(DevHandle handle, struct RtcTime *time); 143``` 144 145 **Table 5** Description of RtcReadTime 146 147| **Parameter**| **Description**| 148| -------- | -------- | 149| handle | RTC device handle. | 150| time | RTC time information, which includes the year, month, day, day of the week, hour, minute, second, and millisecond.| 151| **Return Value**| **Description** | 152| 0 | The operation is successful. | 153| Negative value | The operation failed. | 154 155 156``` 157int32_t ret; 158struct RtcTime tm; 159 160/* Read RTC time from the RTC driver. */ 161ret = RtcReadTime(handle, &tm); 162if (ret != 0) { 163 /* Error handling. */ 164} 165``` 166 167- Setting the RTC time 168 169Call **RtcWriteTime()** to set the RTC time. 170 171```c 172int32_t RtcWriteTime(DevHandle handle, struct RtcTime *time); 173``` 174 175 **Table 6** Description of RtcWriteTime 176 177| **Parameter**| **Description**| 178| -------- | -------- | 179| handle | RTC device handle.| 180| time | RTC time to set, which includes the year, month, day, day of the week, hour, minute, second, and millisecond.| 181| **Return Value**| **Description**| 182| 0 | The operation is successful.| 183| Negative value| The operation failed.| 184 185> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> 186> 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 manual of the device you use. You do not need to set the day of week. 187 188 189``` 190int32_t ret; 191struct RtcTime tm; 192 193/* Set the RTC time to UTC 2020/01/01 00:59:00 .000. */ 194tm.year = 2020; 195tm.month = 01; 196tm.day = 01; 197tm.hour= 00; 198tm.minute = 59; 199tm.second = 00; 200tm.millisecond = 0; 201/* Write the RTC time. */ 202ret = RtcWriteTime(handle, &tm); 203if (ret != 0) { 204 /* Error handling. */ 205} 206``` 207 208- Reading the RTC alarm time 209 210Call **RtcReadAlarm()** to obtain the RTC alarm time. 211 212```c 213int32_t RtcReadAlarm(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime *time); 214``` 215 216 **Table 7** Description of RtcReadAlarm 217 218| **Parameter**| **Description**| 219| -------- | -------- | 220| handle | RTC device handle.| 221| alarmIndex | Alarm index.| 222| time | RTC alarm time information, which includes the year, month, day, day of the week, hour, minute, second, and millisecond.| 223| **Return Value**| **Description**| 224| 0 | The operation is successful.| 225| Negative value | The operation failed.| 226 227 228``` 229int32_t ret; 230struct RtcTime alarmTime; 231 232/* Read the RTC alarm time of alarm RTC_ALARM_INDEX_A. */ 233ret = RtcReadAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); 234if (ret != 0) { 235 /* Error handling. */ 236} 237``` 238 239- Setting the RTC alarm time 240 241Call **RtcWriteAlarm()** to set the RTC alarm time based on the alarm index. 242 243```c 244int32_t RtcWriteAlarm(DevHandle handle, enum RtcAlarmIndex alarmIndex, struct RtcTime *time); 245``` 246 247 **Table 8** Description of RtcWriteAlarm 248 249| **Parameter**| **Description**| 250| -------- | -------- | 251| handle | RTC device handle.| 252| alarmIndex | Alarm index.| 253| time | RTC alarm time to set, which includes the year, month, day, day of the week, hour, minute, second, and millisecond.| 254| **Return Value**| **Description**| 255| 0 | The operation is successful.| 256| Negative value| The operation failed.| 257 258> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br> 259> 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 manual of the device you use. You do not need to set the day of week. 260 261 262``` 263int32_t ret; 264struct RtcTime alarmTime; 265 266/* Set the RTC alarm time to 2020/01/01 00:59:59 .000. */ 267alarmTime.year = 2020; 268alarmTime.month = 01; 269alarmTime.day = 01; 270alarmTime.hour = 00; 271alarmTime.minute = 59; 272alarmTime.second = 59; 273alarmTime.millisecond = 0; 274/* Set the alarm time of alarm RTC_ALARM_INDEX_A. */ 275ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); 276if (ret != 0) { 277 /* Error handling. */ 278} 279``` 280 281- Enabling or disabling alarm interrupts 282 283Call **RtcAlarmInterruptEnable** to enable interrupts for an RTC alarm so that the registered callback can be invoked when the alarm is not generated at the specified time. 284 285```c 286int32_t RtcAlarmInterruptEnable(DevHandle handle, enum RtcAlarmIndex alarmIndex, uint8_t enable); 287``` 288 289 **Table 9** Description of RtcAlarmInterruptEnable 290 291| **Parameter**| **Description**| 292| -------- | -------- | 293| handle | RTC device handle.| 294| alarmIndex | Alarm index.| 295| enable | Whether to enable RTC alarm interrupts. The value **1** means to enable interrupts and **0** means to disable interrupts.| 296| **Return Value**| **Description**| 297| 0 | The operation is successful.| 298| Negative value| The operation failed.| 299 300 301``` 302int32_t ret; 303 304/* Enable interrupts for an RTC alarm. */ 305ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); 306if (ret != 0) { 307 /* Error handling. */ 308} 309``` 310 311- Obtaining the RTC external frequency 312 313Call **RtcGetFreq()** to obtain the frequency of the external crystal oscillator connected to the RTC driver. 314 315```c 316int32_t RtcGetFreq(DevHandle handle, uint32_t *freq); 317``` 318 319 **Table 10** Description of RtcGetFreq 320 321| **Parameter**| **Description**| 322| -------- | -------- | 323| handle | RTC device handle.| 324| freq | Pointer to the frequency of the external crystal oscillator, in Hz.| 325| **Return Value**| **Description**| 326| 0 | The operation is successful.| 327| Negative value| The operation failed.| 328 329 330``` 331int32_t ret; 332uint32_t freq = 0; 333 334/* Obtain the frequency of the external crystal oscillator connected to the RTC driver. */ 335ret = RtcGetFreq(handle, &freq); 336if (ret != 0) { 337 /* Error handling. */ 338} 339``` 340 341- Setting the RTC external frequency 342 343Call **RtcSetFreq()** to set the frequency of the external crystal oscillator connected to the RTC driver. 344 345```c 346int32_t RtcSetFreq(DevHandle handle, uint32_t freq); 347``` 348 349 **Table 11** Description of RtcSetFreq 350 351| **Parameter**| **Description**| 352| -------- | -------- | 353| handle | RTC device handle.| 354| freq | Pointer to the frequency to set for the external crystal oscillator, in Hz.| 355| **Return Value**| **Description**| 356| 0 | The operation is successful.| 357| Negative value| The operation failed.| 358 359 360``` 361int32_t ret; 362uint32_t freq = 32768; /* 32768 Hz */ 363 364/* Set the frequency of the external crystal oscillator based on the requirements specified in the manual of the device you use. */ 365ret = RtcSetFreq(handle, freq); 366if (ret != 0) { 367 /* Error handling. */ 368} 369``` 370 371- Resetting the RTC 372 373Call **RtcReset()** to reset the RTC. After the reset, the registers are restored to default values. 374 375```c 376int32_t RtcReset(DevHandle handle); 377``` 378 379 **Table 12** Description of RtcReset 380 381| **Parameter**| **Description**| 382| -------- | -------- | 383| handle | RTC device handle.| 384| **Return Value**| **Description**| 385| 0 | The operation is successful.| 386| Negative value| The operation failed.| 387 388 389``` 390int32_t ret; 391 392/* Reset the RTC to restore default values of registers. */ 393ret = RtcReset(handle); 394if (ret != 0) { 395 /* Error handling. */ 396} 397``` 398 399- Reading a custom RTC register 400 401Call **RtcReadReg()** to read the configuration of a custom RTC register based on the register index. One index corresponds to one byte of the register value. 402 403```c 404int32_t RtcReadReg(DevHandle handle, uint8_t usrDefIndex, uint8_t *value); 405``` 406 407 **Table 13** Description of RtcReadReg 408 409| **Parameter**| **Description**| 410| -------- | -------- | 411| handle | RTC device handle.| 412| usrDefIndex | Index of the custom register.| 413| value | Register value.| 414| **Return Value** | **Description**| 415| 0 | The operation is successful.| 416| Negative value| The operation failed.| 417 418 419``` 420int32_t ret; 421uint8_t usrDefIndex = 0; /* Define index 0 for the first custom register. */ 422uint8_t value = 0; 423 424/* Read the value of custom RTC register 0. One index corresponds to one byte of the register value. */ 425ret = RtcReadReg(handle, usrDefIndex, &value); 426if (ret != 0) { 427 /* Error handling. */ 428} 429``` 430 431- Setting a custom RTC register 432 433Call **RtcWriteReg()** to set a register based on the specified register index. One index corresponds to one byte of the register value. 434 435```c 436int32_t RtcWriteReg(DevHandle handle, uint8_t usrDefIndex, uint8_t value); 437``` 438 439 **Table 14** Description of RtcWriteReg 440 441| **Parameter**| **Description**| 442| -------- | -------- | 443| handle | RTC device handle.| 444| usrDefIndex | Index of the custom register.| 445| value | Register value.| 446| **Return Value** | **Description**| 447| 0 | The operation is successful.| 448| Negative value| The operation failed.| 449 450 451``` 452int32_t ret; 453uint8_t usrDefIndex = 0; /* Define index 0 for the first custom register. */ 454uint8_t value = 0x10; 455 456/* Set a value for register 0. One index corresponds to one byte of the configuration value. */ 457ret = RtcWriteReg(handle, usrDefIndex, value); 458if (ret != 0) { 459 /* Error handling. */ 460} 461``` 462 463 464## Example 465 466The procedure is as follows: 467 4681. During the OS startup, the HDF identifies the RTC device in the system. 469 4702. The HDF initializes and creates the RTC device. 471 4723. Call APIs to perform operations on the RTC device. 473 4744. Close the RTC device handle to release resources. 475 476The sample code is as follows: 477 478 479``` 480#include "rtc_if.h" 481int32_t RtcAlarmACallback(enum RtcAlarmIndex alarmIndex) 482{ 483 if (alarmIndex == RTC_ALARM_INDEX_A) { 484 /* Processing of alarm A. */ 485 printf("RTC Alarm A callback function\n\r"); 486 } else if (alarmIndex == RTC_ALARM_INDEX_B) { 487 /* Processing of alarm B. */ 488 printf("RTC Alarm B callback function\n\r"); 489 } else { 490 /* Error handling. */ 491 } 492 return 0; 493} 494 495void RtcTestSample(void) 496{ 497 int32_t ret; 498 struct RtcTime tm; 499 struct RtcTime alarmTime; 500 uint32_t freq; 501 DevHandle handle = NULL; 502 503 /* Open the RTC device handle. */ 504 handle = RtcOpen(); 505 if (handle == NULL) { 506 /* Error handling. */ 507 } 508 /* Register a callback for alarm A if it is not generated at the specified time. */ 509 ret = RtcRegisterAlarmCallback(handle, RTC_ALARM_INDEX_A, RtcAlarmACallback); 510 if (ret != 0) { 511 /* Error handling. */ 512 } 513 /* Set the frequency of the external crystal oscillator based on the requirements specified in the manual of the device you use. */ 514 freq = 32768; /* 32768 Hz */ 515 ret = RtcSetFreq(handle, freq); 516 if (ret != 0) { 517 /* Error handling. */ 518 } 519 /* Enable interrupts for RTC alarm A. */ 520 ret = RtcAlarmInterruptEnable(handle, RTC_ALARM_INDEX_A, 1); 521 if (ret != 0) { 522 /* Error handling. */ 523 } 524 /* Set the RTC time to 2020/01/01 00:00:10 .990. */ 525 tm.year = 2020; 526 tm.month = 01; 527 tm.day = 01; 528 tm.hour= 0; 529 tm.minute = 0; 530 tm.second = 10; 531 tm.millisecond = 990; 532 /* Write the RTC time. */ 533 ret = RtcWriteTime(handle, &tm); 534 if (ret != 0) { 535 /* Error handling. */ 536 } 537 /* Set the RTC alarm time to 2020/01/01 00:00:30 .100. */ 538 alarmTime.year = 2020; 539 alarmTime.month = 01; 540 alarmTime.day = 01; 541 alarmTime.hour = 0; 542 alarmTime.minute = 0; 543 alarmTime.second = 30; 544 alarmTime.millisecond = 100; 545 /* Set the alarm time for RTC_ALARM_INDEX_A. When the specified time is reached, "RTC Alarm A callback function" will be printed. */ 546 ret = RtcWriteAlarm(handle, RTC_ALARM_INDEX_A, &alarmTime); 547 if (ret != 0) { 548 /* Error handling. */ 549 } 550 551 /* Read the RTC time. */ 552 ret = RtcReadTime(handle, &tm); 553 if (ret != 0) { 554 /* Error handling. */ 555 } 556 sleep(5) 557 printf("RTC read time:\n\r"); 558 printf("year-month-date-weekday hour:minute:second .millisecond %04u-%02u-%02u-%u %02u:%02u:%02u .%03u", 559 tm.year, tm.month, tm.day, tm.weekday, tm.hour, tm.minute, tm.second, tm.millisecond); 560 /* Close the RTC device handle. */ 561 RtcClose(handle); 562} 563``` 564