1 /*
2  * Copyright (c) 2012 - 2024, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef NRF_TEMP_H__
35 #define NRF_TEMP_H__
36 
37 #include <nrfx.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /**
44 * @defgroup nrf_temp_hal TEMP HAL
45 * @{
46 * @ingroup nrf_temp
47 * @brief   Hardware access layer for managing the Temperature sensor (TEMP).
48 */
49 
50 #if defined(TEMP_CALIB_CALIB_Msk) || defined(__NRFX_DOXYGEN__)
51 /** @brief Symbol indicating whether the calibration of temperature measurement is present. */
52 #define NRF_TEMP_HAS_CALIBRATION 1
53 #else
54 #define NRF_TEMP_HAS_CALIBRATION 0
55 #endif
56 
57 /** @brief TEMP tasks. */
58 typedef enum
59 {
60     NRF_TEMP_TASK_START = offsetof(NRF_TEMP_Type, TASKS_START), /**< Start temperature measurement. */
61     NRF_TEMP_TASK_STOP  = offsetof(NRF_TEMP_Type, TASKS_STOP)   /**< Stop temperature measurement. */
62 } nrf_temp_task_t;
63 
64 /** @brief TEMP events. */
65 typedef enum
66 {
67     NRF_TEMP_EVENT_DATARDY = offsetof(NRF_TEMP_Type, EVENTS_DATARDY) /**< Temperature measurement complete, data ready. */
68 } nrf_temp_event_t;
69 
70 /** @brief TEMP interrupts. */
71 typedef enum
72 {
73     NRF_TEMP_INT_DATARDY_MASK = TEMP_INTENSET_DATARDY_Msk /**< Interrupt on DATARDY event.  */
74 } nrf_temp_int_mask_t;
75 
76 /**
77  * @brief Function for enabling specified interrupts.
78  *
79  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
80  * @param[in] mask  Mask of interrupts to be enabled.
81  *                  Use @ref nrf_temp_int_mask_t values for bit masking.
82  */
83 NRF_STATIC_INLINE void nrf_temp_int_enable(NRF_TEMP_Type * p_reg, uint32_t mask);
84 
85 /**
86  * @brief Function for disabling specified interrupts.
87  *
88  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
89  * @param[in] mask  Mask of interrupts to be disabled.
90  *                  Use @ref nrf_temp_int_mask_t values for bit masking.
91  */
92 NRF_STATIC_INLINE void nrf_temp_int_disable(NRF_TEMP_Type * p_reg, uint32_t mask);
93 
94 /**
95  * @brief Function for checking if the specified interrupts are enabled.
96  *
97  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
98  * @param[in] mask  Mask of interrupts to be checked.
99  *                  Use @ref nrf_temp_int_mask_t values for bit masking.
100  *
101  * @return Mask of enabled interrupts.
102  */
103 NRF_STATIC_INLINE uint32_t nrf_temp_int_enable_check(NRF_TEMP_Type const * p_reg, uint32_t mask);
104 
105 /**
106  * @brief Function for getting the address of the specified TEMP task register.
107  *
108  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
109  * @param[in] task  Requested task.
110  *
111  * @return Address of the requested task register.
112  */
113 NRF_STATIC_INLINE uint32_t nrf_temp_task_address_get(NRF_TEMP_Type const * p_reg,
114                                                      nrf_temp_task_t       task);
115 
116 /**
117  * @brief Function for activating the specified TEMP task.
118  *
119  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
120  * @param[in] task  Task to be activated.
121  */
122 NRF_STATIC_INLINE void nrf_temp_task_trigger(NRF_TEMP_Type * p_reg, nrf_temp_task_t task);
123 
124 /**
125  * @brief Function for getting the address of the specified TEMP event register.
126  *
127  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
128  * @param[in] event Requested event.
129  *
130  * @return Address of the requested event register.
131  */
132 NRF_STATIC_INLINE uint32_t nrf_temp_event_address_get(NRF_TEMP_Type const * p_reg,
133                                                       nrf_temp_event_t      event);
134 
135 /**
136  * @brief Function for clearing the specified TEMP event.
137  *
138  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
139  * @param[in] event Event to clear.
140  */
141 NRF_STATIC_INLINE void nrf_temp_event_clear(NRF_TEMP_Type *  p_reg, nrf_temp_event_t event);
142 
143 /**
144  * @brief Function for getting the state of a specific event.
145  *
146  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
147  * @param[in] event Event to be checked.
148  *
149  * @retval true  The event has been generated.
150  * @retval false The event has not been generated.
151  */
152 NRF_STATIC_INLINE bool nrf_temp_event_check(NRF_TEMP_Type const * p_reg, nrf_temp_event_t event);
153 
154 /**
155  * @brief Function for getting the result of temperature measurement.
156  *
157  * @note Returned value is in 2's complement format, 0.25 °C steps
158  *
159  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
160  *
161  * @return Temperature value register contents.
162  */
163 NRF_STATIC_INLINE int32_t nrf_temp_result_get(NRF_TEMP_Type const * p_reg);
164 
165 #if NRF_TEMP_HAS_CALIBRATION
166 /**
167  * @brief Function for setting the calibration coefficient for the temperature measurement.
168  *
169  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
170  * @param[in] coeff Calibration coefficient.
171  */
172 NRF_STATIC_INLINE void nrf_temp_calibration_coeff_set(NRF_TEMP_Type * p_reg, uint32_t coeff);
173 
174 /**
175  * @brief Function for getting the calibration coefficient for the temperature measurement.
176  *
177  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
178  *
179  * @return Calibration coefficient.
180  */
181 NRF_STATIC_INLINE uint32_t nrf_temp_calibration_coeff_get(NRF_TEMP_Type const * p_reg);
182 #endif
183 
184 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
185 /**
186  * @brief Function for setting the subscribe configuration for a given
187  *        TEMP task.
188  *
189  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
190  * @param[in] task    Task for which to set the configuration.
191  * @param[in] channel Channel through which to subscribe events.
192  */
193 NRF_STATIC_INLINE void nrf_temp_subscribe_set(NRF_TEMP_Type * p_reg,
194                                               nrf_temp_task_t task,
195                                               uint8_t         channel);
196 
197 /**
198  * @brief Function for clearing the subscribe configuration for a given
199  *        TEMP task.
200  *
201  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
202  * @param[in] task  Task for which to clear the configuration.
203  */
204 NRF_STATIC_INLINE void nrf_temp_subscribe_clear(NRF_TEMP_Type * p_reg,
205                                                 nrf_temp_task_t task);
206 
207 /**
208  * @brief Function for setting the publish configuration for a given
209  *        TEMP event.
210  *
211  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
212  * @param[in] event   Event for which to set the configuration.
213  * @param[in] channel Channel through which to publish the event.
214  */
215 NRF_STATIC_INLINE void nrf_temp_publish_set(NRF_TEMP_Type *  p_reg,
216                                             nrf_temp_event_t event,
217                                             uint8_t          channel);
218 
219 /**
220  * @brief Function for clearing the publish configuration for a given
221  *        TEMP event.
222  *
223  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
224  * @param[in] event Event for which to clear the configuration.
225  */
226 NRF_STATIC_INLINE void nrf_temp_publish_clear(NRF_TEMP_Type *  p_reg,
227                                               nrf_temp_event_t event);
228 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
229 
230 #ifndef NRF_DECLARE_ONLY
231 
nrf_temp_int_enable(NRF_TEMP_Type * p_reg,uint32_t mask)232 NRF_STATIC_INLINE void nrf_temp_int_enable(NRF_TEMP_Type * p_reg, uint32_t mask)
233 {
234     p_reg->INTENSET = mask;
235 }
236 
nrf_temp_int_disable(NRF_TEMP_Type * p_reg,uint32_t mask)237 NRF_STATIC_INLINE void nrf_temp_int_disable(NRF_TEMP_Type * p_reg, uint32_t mask)
238 {
239     p_reg->INTENCLR = mask;
240 }
241 
nrf_temp_int_enable_check(NRF_TEMP_Type const * p_reg,uint32_t mask)242 NRF_STATIC_INLINE uint32_t nrf_temp_int_enable_check(NRF_TEMP_Type const * p_reg, uint32_t mask)
243 {
244     return p_reg->INTENSET & mask;
245 }
246 
nrf_temp_task_address_get(NRF_TEMP_Type const * p_reg,nrf_temp_task_t task)247 NRF_STATIC_INLINE uint32_t nrf_temp_task_address_get(NRF_TEMP_Type const * p_reg,
248                                                      nrf_temp_task_t       task)
249 {
250     return nrf_task_event_address_get(p_reg, task);
251 }
252 
nrf_temp_task_trigger(NRF_TEMP_Type * p_reg,nrf_temp_task_t task)253 NRF_STATIC_INLINE void nrf_temp_task_trigger(NRF_TEMP_Type * p_reg, nrf_temp_task_t task)
254 {
255     *(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task) = 1;
256 }
257 
nrf_temp_event_address_get(NRF_TEMP_Type const * p_reg,nrf_temp_event_t event)258 NRF_STATIC_INLINE uint32_t nrf_temp_event_address_get(NRF_TEMP_Type const * p_reg,
259                                                       nrf_temp_event_t      event)
260 {
261     return nrf_task_event_address_get(p_reg, event);
262 }
263 
nrf_temp_event_clear(NRF_TEMP_Type * p_reg,nrf_temp_event_t event)264 NRF_STATIC_INLINE void nrf_temp_event_clear(NRF_TEMP_Type * p_reg, nrf_temp_event_t event)
265 {
266     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0;
267     nrf_event_readback((uint8_t *)p_reg + (uint32_t)event);
268 }
269 
nrf_temp_event_check(NRF_TEMP_Type const * p_reg,nrf_temp_event_t event)270 NRF_STATIC_INLINE bool nrf_temp_event_check(NRF_TEMP_Type const * p_reg, nrf_temp_event_t event)
271 {
272     return nrf_event_check(p_reg, event);
273 }
274 
nrf_temp_result_get(NRF_TEMP_Type const * p_reg)275 NRF_STATIC_INLINE int32_t nrf_temp_result_get(NRF_TEMP_Type const * p_reg)
276 {
277     int32_t raw_measurement = p_reg->TEMP;
278 
279 #if defined(NRF51)
280     /* Apply workaround for the nRF51 series anomaly 28 - TEMP: Negative measured values are not represented correctly. */
281     if ((raw_measurement & 0x00000200) != 0)
282     {
283         raw_measurement |= (int32_t)0xFFFFFC00;
284     }
285 #endif
286 
287     return raw_measurement;
288 }
289 
290 #if NRF_TEMP_HAS_CALIBRATION
nrf_temp_calibration_coeff_set(NRF_TEMP_Type * p_reg,uint32_t coeff)291 NRF_STATIC_INLINE void nrf_temp_calibration_coeff_set(NRF_TEMP_Type * p_reg, uint32_t coeff)
292 {
293     p_reg->CALIB = coeff;
294 }
295 
nrf_temp_calibration_coeff_get(NRF_TEMP_Type const * p_reg)296 NRF_STATIC_INLINE uint32_t nrf_temp_calibration_coeff_get(NRF_TEMP_Type const * p_reg)
297 {
298     return p_reg->CALIB;
299 }
300 #endif
301 
302 #if defined(DPPI_PRESENT)
nrf_temp_subscribe_set(NRF_TEMP_Type * p_reg,nrf_temp_task_t task,uint8_t channel)303 NRF_STATIC_INLINE void nrf_temp_subscribe_set(NRF_TEMP_Type * p_reg,
304                                               nrf_temp_task_t task,
305                                               uint8_t         channel)
306 {
307     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
308             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
309 }
310 
nrf_temp_subscribe_clear(NRF_TEMP_Type * p_reg,nrf_temp_task_t task)311 NRF_STATIC_INLINE void nrf_temp_subscribe_clear(NRF_TEMP_Type * p_reg,
312                                                 nrf_temp_task_t task)
313 {
314     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
315 }
316 
nrf_temp_publish_set(NRF_TEMP_Type * p_reg,nrf_temp_event_t event,uint8_t channel)317 NRF_STATIC_INLINE void nrf_temp_publish_set(NRF_TEMP_Type *  p_reg,
318                                             nrf_temp_event_t event,
319                                             uint8_t          channel)
320 {
321     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
322             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
323 }
324 
nrf_temp_publish_clear(NRF_TEMP_Type * p_reg,nrf_temp_event_t event)325 NRF_STATIC_INLINE void nrf_temp_publish_clear(NRF_TEMP_Type *  p_reg,
326                                               nrf_temp_event_t event)
327 {
328     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
329 }
330 #endif // defined(DPPI_PRESENT)
331 
332 #endif // NRF_DECLARE_ONLY
333 
334 /** @} */
335 
336 #ifdef __cplusplus
337 }
338 #endif
339 
340 #endif // NRF_TEMP_H__
341