1 /**
2 ******************************************************************************
3 * @file ald_rtchw.c
4 * @brief RTCHW module driver.
5 * This file provides firmware functions to manage the following
6 * functionalities of the RTC peripheral:
7 * + Calibration functions
8 * @version V1.0
9 * @date 25 Apr 2019
10 * @author AE Team
11 * @note
12 * Change Logs:
13 * Date Author Notes
14 * 25 Apr 2019 AE Team The first version
15 *
16 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
17 *
18 * SPDX-License-Identifier: Apache-2.0
19 *
20 * Licensed under the Apache License, Version 2.0 (the License); you may
21 * not use this file except in compliance with the License.
22 * You may obtain a copy of the License at
23 *
24 * www.apache.org/licenses/LICENSE-2.0
25 *
26 * Unless required by applicable law or agreed to in writing, software
27 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
28 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29 * See the License for the specific language governing permissions and
30 * limitations under the License.
31 **********************************************************************************
32 */
33
34 #include "ald_conf.h"
35
36 /** @addtogroup ES32FXXX_ALD
37 * @{
38 */
39
40 /** @defgroup RTCHW RTCHW
41 * @brief RTCHW module driver
42 * @{
43 */
44 #ifdef ALD_RTC
45
46 /** @addtogroup RTCHW_Private_Functions RTCHW Private Functions
47 * @{
48 */
49 /**
50 * @brief delay losc clock
51 * @param u: clock numbers.
52 * @retval None.
53 */
delay_losc_clk(uint16_t u)54 static void delay_losc_clk(uint16_t u)
55 {
56 uint16_t i, j;
57
58 for (i = 0; i < u; i++) {
59 for (j = 0; j < 60; j++) {
60 __ASM volatile ("nop");
61 }
62 }
63 }
64
65 /**
66 * @brief Check parameter for calibation
67 * @param config: pointer to rtc_hw_cali_offset_t structure.
68 * @param mode: Running mode, see @ref rtc_hw_cali_mode_t.
69 * @retval Status.
70 */
rtc_hw_auto_check(rtc_hw_cali_offset_t * config,rtc_hw_cali_mode_t mode)71 static uint8_t rtc_hw_auto_check(rtc_hw_cali_offset_t *config, rtc_hw_cali_mode_t mode)
72 {
73 uint8_t tom = READ_BITS(TSENSE->CR, TSENSE_CR_TOM_MSK, TSENSE_CR_TOM_POSS);
74 uint8_t shift[8] = {0, 2, 4, 6, 8, 8, 8, 8};
75
76 if (mode == RTC_CALI_MODE_NORMAL) {
77 if ((RTC->CALCON & 0x1F3000F) != (RTCINFO->RTC_CALCR & 0x1F3000F))
78 return 1;
79 }
80 else {
81 if ((RTC->CALCON & 0x183000F) != (RTCINFO->RTC_CALCR & 0x183000F))
82 return 1;
83
84 if (READ_BITS(RTC->CALCON, RTC_CALCON_TCP_MSK, RTC_CALCON_TCP_POSS) != 7) /* when sleep mode */
85 return 1;
86 }
87
88 if ((TSENSE->CR & 0x7702) != (RTCINFO->TEMP_CR & 0x7702))
89 return 1;
90 if (RTC->TEMPBDR != RTCINFO->RTC_TEMPBDR + config->offset_rtc_bdr)
91 return 1;
92 if (RTC->LTAXR != RTCINFO->RTC_LTAXR + config->offset_ltaxr)
93 return 1;
94 if (RTC->HTAXR != RTCINFO->RTC_HTAXR + config->offset_htaxr)
95 return 1;
96 if (RTC->HTAXR != RTCINFO->RTC_HTCAR + config->offset_htcar)
97 return 1;
98 if (RTC->HTCBR != RTCINFO->RTC_HTCBR + config->offset_htcbr)
99 return 1;
100 if (RTC->HTCCR != RTCINFO->RTC_HTCCR + config->offset_htccr)
101 return 1;
102 if (RTC->HTCDR != RTCINFO->RTC_HTCDR + config->offset_htcdr)
103 return 1;
104 if (RTC->HTCER != RTCINFO->RTC_HTCER + config->offset_htcer)
105 return 1;
106 if (RTC->LTAXR != RTCINFO->RTC_LTCAR + config->offset_ltcar)
107 return 1;
108 if (RTC->LTCBR != RTCINFO->RTC_LTCBR + config->offset_ltcbr)
109 return 1;
110 if (RTC->LTCCR != RTCINFO->RTC_LTCCR + config->offset_ltccr)
111 return 1;
112 if (RTC->LTCDR != RTCINFO->RTC_LTCDR + config->offset_ltcdr)
113 return 1;
114 if (RTC->LTCER != RTCINFO->RTC_LTCER + config->offset_ltcer)
115 return 1;
116 if (TSENSE->TBDR != (RTCINFO->TEMP_TBDR & 0xFFFF) + config->offset_temp_bdr)
117 return 1;
118 if (TSENSE->LTGR != RTCINFO->TEMP_LTGR + config->offset_ltgr)
119 return 1;
120 if (TSENSE->HTGR != RTCINFO->TEMP_HTGR + config->offset_htgr)
121 return 1;
122 if (TSENSE->TCALBDR != (((RTCINFO->TEMP_TCALBDR & 0x1FFFFFF) >> shift[tom]) & 0x1FFFF)
123 + config->offset_tcalbdr)
124 return 1;
125
126 return 0;
127 }
128 /**
129 * @}
130 */
131
132 /** @defgroup RTCHW_Public_Functions RTCHW Public Functions
133 * @{
134 */
135 /**
136 * @brief Hardware automatic calibate
137 * @param config: pointer to rtc_hw_cali_offset_t structure.
138 * @param mode: Running mode, see @ref rtc_hw_cali_mode_t
139 * @retval None
140 */
ald_rtc_hw_auto_cali(rtc_hw_cali_offset_t * config,rtc_hw_cali_mode_t mode)141 void ald_rtc_hw_auto_cali(rtc_hw_cali_offset_t *config, rtc_hw_cali_mode_t mode)
142 {
143 uint8_t shift[8] = {0, 2, 4, 6, 8, 8, 8, 8};
144 uint8_t tmp;
145 uint32_t v = 0;
146 uint16_t temp_calf;
147
148 if (!(rtc_hw_auto_check(config, mode)))
149 return;
150
151 RTC_UNLOCK();
152 RTC_CALI_UNLOCK();
153 TSENSE_UNLOCK();
154
155 temp_calf = (uint16_t)RTC->CALDR;
156 while ((READ_BITS(RTC->IFR, RTC_IFR_TCCF_MSK, RTC_IFR_TCCF_POS) == 1) && (v < 0x20000)) /* no usr trig */
157 v++;
158
159 MODIFY_REG(RTC->CALCON, RTC_CALCON_TCM_MSK, 0 << RTC_CALCON_TCM_POSS); /* disable auto compensation */
160 MODIFY_REG(TSENSE->CR, TSENSE_CR_REQEN_MSK, 0 << TSENSE_CR_REQEN_POS); /* disable temp */
161
162 RTC->CALDR = temp_calf;
163 delay_losc_clk(3);
164
165 if (mode == RTC_CALI_MODE_NORMAL) {
166 v = RTC->CALCON & ~0x01F0000F;
167 RTC->CALCON = v | (RTCINFO->RTC_CALCR & 0x01F0000F);
168 }
169 else {
170 v = RTC->CALCON & ~0x0180000F;
171 RTC->CALCON = v | (RTCINFO->RTC_CALCR & 0x0180000F);
172 MODIFY_REG(RTC->CALCON, RTC_CALCON_TCP_MSK, 7 << RTC_CALCON_TCP_POSS); // when sleep mode, caluate once in 1h
173 }
174
175 RTC->TEMPBDR = RTCINFO->RTC_TEMPBDR + config->offset_rtc_bdr;
176 RTC->LTAXR = RTCINFO->RTC_LTAXR + config->offset_ltaxr;
177 RTC->HTAXR = RTCINFO->RTC_HTAXR + config->offset_htaxr;
178 RTC->LTCAR = RTCINFO->RTC_LTCAR + config->offset_ltcar;
179 RTC->LTCBR = RTCINFO->RTC_LTCBR + config->offset_ltcbr;
180 RTC->LTCCR = RTCINFO->RTC_LTCCR + config->offset_ltccr;
181 RTC->LTCDR = RTCINFO->RTC_LTCDR + config->offset_ltcdr;
182 RTC->LTCER = RTCINFO->RTC_LTCER + config->offset_ltcer;
183 RTC->HTCAR = RTCINFO->RTC_HTCAR + config->offset_htcar;
184 RTC->HTCBR = RTCINFO->RTC_HTCBR + config->offset_htcbr;
185 RTC->HTCCR = RTCINFO->RTC_HTCCR + config->offset_htccr;
186 RTC->HTCDR = RTCINFO->RTC_HTCDR + config->offset_htcdr;
187 RTC->HTCER = RTCINFO->RTC_HTCER + config->offset_htcer;
188 MODIFY_REG(RTC->CON, RTC_CON_CKOS_MSK, 5 << RTC_CON_CKOS_POSS); /* output accuracy 1Hz */
189
190 v = TSENSE->CR & ~0x00007700;
191 TSENSE->CR = v | (RTCINFO->TEMP_CR & 0x00007700);
192 TSENSE->HTGR = RTCINFO->TEMP_HTGR + config->offset_htgr;
193 TSENSE->LTGR = RTCINFO->TEMP_LTGR + config->offset_ltgr;
194 tmp = READ_BITS(RTCINFO->TEMP_CR, TSENSE_CR_TOM_MSK, TSENSE_CR_TOM_POSS);
195 TSENSE->TCALBDR = ((RTCINFO->TEMP_TCALBDR & 0x1FFFFFF) >> shift[tmp]) + config->offset_tcalbdr;
196 TSENSE->TBDR = RTCINFO->TEMP_TBDR + config->offset_temp_bdr;
197
198 delay_losc_clk(3);
199 tmp = READ_BITS(RTCINFO->TEMP_CR, TSENSE_CR_REQEN_MSK, TSENSE_CR_REQEN_POS);
200 MODIFY_REG(TSENSE->CR, TSENSE_CR_REQEN_MSK, tmp << TSENSE_CR_REQEN_POS);
201 MODIFY_REG(RTC->CALCON, RTC_CALCON_TCM_MSK, 3 << RTC_CALCON_TCM_POSS); /* usr trig */
202
203 delay_losc_clk(3);
204 MODIFY_REG(RTC->TEMPR, RTC_TEMPR_VAL_MSK, 1 << RTC_TEMPR_VAL_POSS); /* trig immediate*/
205
206 delay_losc_clk(3);
207 tmp = READ_BITS(RTCINFO->RTC_CALCR, RTC_CALCON_TCM_MSK, RTC_CALCON_TCM_POSS);
208 MODIFY_REG(RTC->CALCON, RTC_CALCON_TCM_MSK, tmp << RTC_CALCON_TCM_POSS);
209
210 RTC_CALI_LOCK();
211 RTC_LOCK();
212 TSENSE_LOCK();
213 return;
214 }
215 /**
216 * @}
217 */
218 #endif /* ALD_RTC */
219 /**
220 * @}
221 */
222 /**
223 * @}
224 */
225