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