1 /**
2   *********************************************************************************
3   *
4   * @file    ald_tsense.c
5   * @brief   TSENSE module driver.
6   *
7   * @version V1.0
8   * @date    26 Jun 2019
9   * @author  AE Team
10   * @note
11   *          Change Logs:
12   *          Date            Author          Notes
13   *          26 Jun 2019     AE Team         The first version
14   *
15   * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
16   *
17   * SPDX-License-Identifier: Apache-2.0
18   *
19   * Licensed under the Apache License, Version 2.0 (the License); you may
20   * not use this file except in compliance with the License.
21   * You may obtain a copy of the License at
22   *
23   * www.apache.org/licenses/LICENSE-2.0
24   *
25   * Unless required by applicable law or agreed to in writing, software
26   * distributed under the License is distributed on an AS IS BASIS, WITHOUT
27   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28   * See the License for the specific language governing permissions and
29   * limitations under the License.
30   **********************************************************************************
31   */
32 
33 #include "ald_conf.h"
34 
35 
36 /** @addtogroup ES32FXXX_ALD
37   * @{
38   */
39 
40 /** @defgroup TSENSE TSENSE
41   * @brief TSENSE module driver
42   * @{
43   */
44 #ifdef ALD_TSENSE
45 
46 
47 /** @defgroup TSENSE_Private_Variables TSENSE Private Variables
48   * @{
49   */
50 tsense_cbk __tsense_cbk;
51 /**
52   * @}
53   */
54 
55 /** @defgroup TSENSE_Public_Functions TSENSE Public Functions
56   * @{
57   */
58 
59 /** @addtogroup TSENSE_Public_Functions_Group1 Initialization functions
60   * @brief Initialization functions
61   *
62   * @verbatim
63   ==============================================================================
64               ##### Initialization functions #####
65   ==============================================================================
66     [..]  This section provides functions allowing to initialize the TSENSE:
67       (+) This parameters can be configured:
68         (++) Update Cycle
69         (++) Output Mode
70         (++) Perscaler
71       (+) Select TSENSE source clock(default LOSC)
72 
73     @endverbatim
74   * @{
75   */
76 
77 /**
78   * @brief  Initializes the TSENSE according to the specified
79   * @retval None
80   */
ald_tsense_init(void)81 void ald_tsense_init(void)
82 {
83 	uint16_t tempt, temptinv;
84 	uint32_t tscic, tscicinv;
85 
86 	TSENSE_UNLOCK();
87 	TSENSE->CR = 0;
88 
89 	SET_BIT(TSENSE->CR, TSENSE_CR_CTN_MSK);
90 	SET_BIT(TSENSE->CR, TSENSE_CR_REQEN_MSK);
91 	MODIFY_REG(TSENSE->CR, TSENSE_CR_TSU_MSK, 0x4 << TSENSE_CR_TSU_POSS);
92 	MODIFY_REG(TSENSE->CR, TSENSE_CR_TOM_MSK, 0x3 << TSENSE_CR_TOM_POSS);
93 	MODIFY_REG(TSENSE->PSR, TSENSE_PSR_PRS_MSK, 0x1 << TSENSE_PSR_PRS_POSS);
94 
95 	TSENSE->HTGR = 0x8564F;
96 	TSENSE->LTGR = 0x87037;
97 	tempt        = *(volatile uint16_t *)0x80348;
98 	temptinv     = *(volatile uint16_t *)0x8034A;
99 	tscic        = *(volatile uint32_t *)0x80350;
100 	tscicinv     = *(volatile uint32_t *)0x80358;
101 
102 	if ((tempt == (uint16_t)(~temptinv)) && (tscic == (~tscicinv))) {
103 		TSENSE->TBDR    = tempt;
104 		TSENSE->TCALBDR = (tscic & 0x1FFFFFF) >> 6;
105 	}
106 	else {
107 		TSENSE->TBDR    = 0x1E00;
108 		TSENSE->TCALBDR = 0x1F849;
109 	}
110 
111 	TSENSE_LOCK();
112 	return;
113 }
114 
115 /**
116   * @brief  Configure the TSENSE source.
117   * @param  sel: TSENSE source type.
118   * @retval None
119   */
ald_tsense_source_select(tsense_source_sel_t sel)120 void ald_tsense_source_select(tsense_source_sel_t sel)
121 {
122 	assert_param(IS_TSENSE_SOURCE_SEL(sel));
123 
124 	BKPC_UNLOCK();
125 	MODIFY_REG(BKPC->PCCR, BKPC_PCCR_TSENSECS_MSK, sel << BKPC_PCCR_TSENSECS_POSS);
126 
127 	if (sel == TSENSE_SOURCE_LOSC) {
128 		SET_BIT(BKPC->CR, BKPC_CR_LOSCEN_MSK);
129 	}
130 	else if (sel == TSENSE_SOURCE_LRC) {
131 		SET_BIT(BKPC->CR, BKPC_CR_LRCEN_MSK);
132 	}
133 	else {
134 		; /* do nothing */
135 	}
136 
137 	BKPC_LOCK();
138 	return;
139 }
140 /**
141   * @}
142   */
143 
144 /** @addtogroup TSENSE_Public_Functions_Group2 Peripheral Control functions
145   * @brief Peripheral Control functions
146   *
147   * @verbatim
148   ==============================================================================
149               ##### Peripheral Control functions #####
150   ==============================================================================
151   [..]  This section provides functions allowing to:
152     (+) ald_tsense_get_value() API can get the current temperature.
153     (+) ald_tsense_get_value_by_it() API can get the current temperature by interrupt.
154     (+) ald_tsense_irq_handler() API can handle the interrupt request.
155 
156     @endverbatim
157   * @{
158   */
159 
160 /**
161   * @brief  Get the current temperature
162   * @param  tsense: The value of current temperature.
163   * @retval ALD status:
164   *         @arg @ref OK    The value is valid
165   *         @arg @ref ERROR The value is invalid
166   */
ald_tsense_get_value(uint16_t * tsense)167 ald_status_t ald_tsense_get_value(uint16_t *tsense)
168 {
169 	uint32_t tmp = 0;
170 
171 	TSENSE_UNLOCK();
172 	SET_BIT(TSENSE->IFCR, TSENSE_IFCR_TSENSE_MSK);
173 	SET_BIT(TSENSE->CR, TSENSE_CR_EN_MSK);
174 	TSENSE_LOCK();
175 
176 	while ((!(READ_BIT(TSENSE->IF, TSENSE_IF_TSENSE_MSK))) && (tmp++ < 1000000));
177 
178 	if (tmp >= 1000000) {
179 		TSENSE_UNLOCK();
180 		CLEAR_BIT(TSENSE->CR, TSENSE_CR_EN_MSK);
181 		TSENSE_LOCK();
182 		return TIMEOUT;
183 	}
184 
185 	TSENSE_UNLOCK();
186 	SET_BIT(TSENSE->IFCR, TSENSE_IFCR_TSENSE_MSK);
187 	TSENSE_LOCK();
188 
189 	if (READ_BIT(TSENSE->DR, TSENSE_DR_ERR_MSK)) {
190 		TSENSE_UNLOCK();
191 		CLEAR_BIT(TSENSE->CR, TSENSE_CR_EN_MSK);
192 		TSENSE_LOCK();
193 		return ERROR;
194 	}
195 
196 	*tsense = READ_BITS(TSENSE->DR, TSENSE_DR_DATA_MSK, TSENSE_DR_DATA_POSS);
197 
198 	TSENSE_UNLOCK();
199 	CLEAR_BIT(TSENSE->CR, TSENSE_CR_EN_MSK);
200 	TSENSE_LOCK();
201 
202 	return OK;
203 }
204 
205 /**
206   * @brief  Get the current temperature by interrupt
207   * @param  cbk: The callback function
208   * @retval None
209   */
ald_tsense_get_value_by_it(tsense_cbk cbk)210 void ald_tsense_get_value_by_it(tsense_cbk cbk)
211 {
212 	__tsense_cbk = cbk;
213 
214 	TSENSE_UNLOCK();
215 	SET_BIT(TSENSE->IFCR, TSENSE_IFCR_TSENSE_MSK);
216 	SET_BIT(TSENSE->IE, TSENSE_IE_TSENSE_MSK);
217 	SET_BIT(TSENSE->CR, TSENSE_CR_EN_MSK);
218 	TSENSE_LOCK();
219 
220 	return;
221 }
222 
223 /**
224   * @brief  This function handles TSENSE interrupt request.
225   * @retval None
226   */
ald_tsense_irq_handler(void)227 void ald_tsense_irq_handler(void)
228 {
229 	TSENSE_UNLOCK();
230 	SET_BIT(TSENSE->IFCR, TSENSE_IFCR_TSENSE_MSK);
231 	TSENSE_LOCK();
232 
233 	if (__tsense_cbk == NULL) {
234 		TSENSE_UNLOCK();
235 		CLEAR_BIT(TSENSE->CR, TSENSE_CR_EN_MSK);
236 		TSENSE_LOCK();
237 		return;
238 	}
239 
240 	if (READ_BIT(TSENSE->DR, TSENSE_DR_ERR_MSK)) {
241 		TSENSE_UNLOCK();
242 		CLEAR_BIT(TSENSE->CR, TSENSE_CR_EN_MSK);
243 		TSENSE_LOCK();
244 		__tsense_cbk(0, ERROR);
245 
246 		return;
247 	}
248 
249 	__tsense_cbk(READ_BITS(TSENSE->DR, TSENSE_DR_DATA_MSK, TSENSE_DR_DATA_POSS), OK);
250 
251 	TSENSE_UNLOCK();
252 	SET_BIT(TSENSE->IFCR, TSENSE_IFCR_TSENSE_MSK);
253 	CLEAR_BIT(TSENSE->CR, TSENSE_CR_EN_MSK);
254 	TSENSE_LOCK();
255 
256 	return;
257 }
258 /**
259   * @}
260   */
261 /**
262   * @}
263   */
264 #endif /* ALD_TSENSE */
265 /**
266   * @}
267   */
268 
269 /**
270   * @}
271   */
272