1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2017-11-06     Haley        the first version
9  */
10 
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include "am_mcu_apollo.h"
14 #include <sys/time.h>
15 
16 #define XT              1
17 #define LFRC            2
18 
19 #define RTC_CLK_SRC     XT
20 
21 //connect am drv to rt drv.
rt_rtc_open(rt_device_t dev,rt_uint16_t oflag)22 static rt_err_t rt_rtc_open(rt_device_t dev, rt_uint16_t oflag)
23 {
24     if (dev->rx_indicate != RT_NULL)
25     {
26         /* Open Interrupt */
27     }
28 
29     return RT_EOK;
30 }
31 
rt_rtc_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)32 static rt_ssize_t rt_rtc_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
33 {
34     return 0;
35 }
36 
rt_rtc_control(rt_device_t dev,int cmd,void * args)37 static rt_err_t rt_rtc_control(rt_device_t dev, int cmd, void *args)
38 {
39     time_t *time;
40     struct tm time_temp;
41     struct tm time_new;
42     am_hal_rtc_time_t hal_time;
43 
44     RT_ASSERT(dev != RT_NULL);
45     rt_memset(&time_temp, 0, sizeof(struct tm));
46 
47     switch (cmd)
48     {
49         case RT_DEVICE_CTRL_RTC_GET_TIME:
50             time = (time_t *)args;
51 
52             /* Get the current Time */
53             am_hal_rtc_time_get(&hal_time);
54 
55             /* Years since 1900 : 0-99 range */
56             time_temp.tm_year = hal_time.ui32Year + 2000 - 1900;
57             /* Months *since* january 0-11 : RTC_Month_Date_Definitions 1 - 12 */
58             time_temp.tm_mon = hal_time.ui32Month - 1;
59             /* Day of the month 1-31 : 1-31 range */
60             time_temp.tm_mday = hal_time.ui32DayOfMonth;
61             /* Hours since midnight 0-23 : 0-23 range */
62             time_temp.tm_hour = hal_time.ui32Hour;
63             /* Minutes 0-59 : the 0-59 range */
64             time_temp.tm_min = hal_time.ui32Minute;
65             /* Seconds 0-59 : the 0-59 range */
66             time_temp.tm_sec = hal_time.ui32Second;
67 
68             *time = timegm(&time_temp);
69 
70             break;
71 
72         case RT_DEVICE_CTRL_RTC_SET_TIME:
73             time = (time_t *)args;
74             gmtime_r(time, &time_new);
75 
76             hal_time.ui32Hour = time_new.tm_hour;
77             hal_time.ui32Minute = time_new.tm_min;
78             hal_time.ui32Second = time_new.tm_sec;
79             hal_time.ui32Hundredths = 00;
80             hal_time.ui32Weekday = time_new.tm_wday;
81             hal_time.ui32DayOfMonth = time_new.tm_mday;
82             hal_time.ui32Month = time_new.tm_mon + 1;
83             hal_time.ui32Year = time_new.tm_year + 1900 - 2000;
84             hal_time.ui32Century = 0;
85 
86             am_hal_rtc_time_set(&hal_time);
87 
88             break;
89     }
90 
91     return RT_EOK;
92 }
93 
rt_hw_rtc_init(void)94 int rt_hw_rtc_init(void)
95 {
96     static struct rt_device rtc;
97 
98 #if RTC_CLK_SRC == LFRC
99     /* Enable the LFRC for the RTC */
100     am_hal_clkgen_osc_start(AM_HAL_CLKGEN_OSC_LFRC);
101 
102     /* Select LFRC for RTC clock source */
103     am_hal_rtc_osc_select(AM_HAL_RTC_OSC_LFRC);
104 #endif
105 
106 #if RTC_CLK_SRC == XT
107     /* Enable the XT for the RTC */
108     am_hal_clkgen_osc_start(AM_HAL_CLKGEN_OSC_XT);
109 
110     /* Select XT for RTC clock source */
111     am_hal_rtc_osc_select(AM_HAL_RTC_OSC_XT);
112 #endif
113 
114     /* Enable the RTC */
115     am_hal_rtc_osc_enable();
116 
117     /* register rtc device */
118     rtc.type    = RT_Device_Class_RTC;
119     rtc.init    = RT_NULL;
120     rtc.open    = rt_rtc_open;
121     rtc.close   = RT_NULL;
122     rtc.read    = rt_rtc_read;
123     rtc.write   = RT_NULL;
124     rtc.control = rt_rtc_control;
125 
126     /* no private */
127     rtc.user_data = RT_NULL;
128 
129     rt_device_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
130 
131     return 0;
132 }
133 #ifdef RT_USING_COMPONENTS_INIT
134 INIT_BOARD_EXPORT(rt_hw_rtc_init);
135 #endif
136 
137 /*@}*/
138