1 /*
2 * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 /**
17 * @file wm_rtc.c
18 *
19 * @brief rtc Driver Module
20 *
21 * @author dave
22 *
23 * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
24 */
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include "wm_regs.h"
29 #include "wm_rtc.h"
30
31 #include "wm_irq.h"
32 #include "tls_common.h"
33
34 struct rtc_irq_context {
35 tls_rtc_irq_callback callback;
36 void *arg;
37 };
38
39 static struct rtc_irq_context rtc_context = {0};
40
41 /**
42 * @brief This function is used to set pmu rtc time
43 *
44 * @param[in] tblock time value
45 *
46 * @return None
47 *
48 * @note None
49 */
tls_set_rtc(struct tm * tblock)50 void tls_set_rtc(struct tm *tblock)
51 {
52 int ctrl1 = 0;
53 int ctrl2 = 0;
54
55 ctrl2 = tls_reg_read32(HR_PMU_RTC_CTRL2); /* disable */
56 ctrl2 &= ~(1 << 16);
57 tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2);
58
59 ctrl1 |= tblock->tm_sec;
60 ctrl1 |= tblock->tm_min << 8;
61 ctrl1 |= tblock->tm_hour << 16;
62 ctrl1 |= tblock->tm_mday << 24;
63 tls_reg_write32(HR_PMU_RTC_CTRL1, ctrl1);
64
65 ctrl2 = 0;
66 ctrl2 |= tblock->tm_mon;
67 ctrl2 |= tblock->tm_year << 8;
68 tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2);
69
70 ctrl2 = tls_reg_read32(HR_PMU_RTC_CTRL2); /* enable */
71 ctrl2 |= (1 << 16);
72 tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2);
73 }
74
75 /**
76 * @brief This function is used to get pmu rtc time
77 *
78 * @param[out] tblock time value
79 *
80 * @return None
81 *
82 * @note None
83 */
tls_get_rtc(struct tm * tblock)84 void tls_get_rtc(struct tm *tblock)
85 {
86 int ctrl1 = 0;
87 int ctrl2 = 0;
88
89 ctrl1 = tls_reg_read32(HR_PMU_RTC_CTRL1);
90 ctrl2 = tls_reg_read32(HR_PMU_RTC_CTRL2);
91 tblock->tm_year = ((int)((int)ctrl2 & 0x00007f00) >> 8);
92 tblock->tm_mon = (ctrl2 & 0x0000000f);
93 tblock->tm_mday = (ctrl1 & 0x1f000000) >> 24;
94 tblock->tm_hour = (ctrl1 & 0x001f0000) >> 16;
95 tblock->tm_min = (ctrl1 & 0x00003f00) >> 8;
96 tblock->tm_sec = ctrl1 & 0x0000003f;
97 }
98
PMU_RTC_IRQHandler(void)99 void PMU_RTC_IRQHandler(void)
100 {
101 tls_reg_write32(HR_PMU_INTERRUPT_SRC, BIT(4)); /* clear rtc interrupt */
102
103 if (rtc_context.callback != NULL)
104 rtc_context.callback(rtc_context.arg);
105
106 return;
107 }
108
109 /**
110 * @brief This function is used to register pmu rtc interrupt
111 *
112 * @param[in] callback the rtc interrupt call back function
113 * @param[in] arg parameter of call back function
114 *
115 * @return None
116 *
117 * @note
118 * user not need clear interrupt flag.
119 * rtc callback function is called in interrupt,
120 * so can not operate the critical data in the callback fuuction,
121 * recommendation to send messages to other tasks to operate it.
122 */
tls_rtc_isr_register(tls_rtc_irq_callback callback,void * arg)123 void tls_rtc_isr_register(tls_rtc_irq_callback callback, void *arg)
124 {
125 rtc_context.callback = callback;
126 rtc_context.arg = arg;
127
128 tls_irq_enable(PMU_IRQn);
129
130 return;
131 }
132
133 /**
134 * @brief This function is used to start pmu rtc timer
135 *
136 * @param[in] tblock timer value
137 *
138 * @return None
139 *
140 * @note None
141 */
tls_rtc_timer_start(struct tm * tblock)142 void tls_rtc_timer_start(struct tm *tblock)
143 {
144 int ctrl1 = 0;
145 int ctrl2 = 0;
146
147 tls_irq_enable(PMU_IRQn);
148
149 ctrl1 |= tblock->tm_sec;
150 ctrl1 |= tblock->tm_min << 8;
151 ctrl1 |= tblock->tm_hour << 16;
152 ctrl1 |= tblock->tm_mday << 24;
153
154 ctrl2 |= tblock->tm_mon;
155 ctrl2 |= tblock->tm_year << 8;
156 tls_reg_write32(HR_PMU_RTC_CTRL2, ctrl2 | BIT(16));
157
158 tls_reg_write32(HR_PMU_RTC_CTRL1, ctrl1 | BIT(31)); /* must set the enable */
159
160 return;
161 }
162
163 /**
164 * @brief This function is used to stop pmu rtc timer
165 *
166 * @param None
167 *
168 * @return None
169 *
170 * @note This function also is used to clear rtc timer interrupt
171 */
tls_rtc_timer_stop(void)172 void tls_rtc_timer_stop(void)
173 {
174 tls_reg_write32(HR_PMU_RTC_CTRL1, tls_reg_read32(HR_PMU_RTC_CTRL1) & (~BIT(31)));
175
176 return;
177 }
178
179