Contiki-NG
Loading...
Searching...
No Matches
nrf_802154_platform_temperature.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2026, RISE Research Institutes of Sweden AB.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30/*---------------------------------------------------------------------------*/
31/**
32 * \file
33 * Temperature platform for nrf_802154 on the nRF5340 network core.
34 *
35 * The library uses the die temperature to compensate the RSSI/ED
36 * readings and the CCA energy-detection threshold (nrf_802154_rssi.c),
37 * so an accurate value improves RSSI/LQI reporting and CCA behavior
38 * across the operating range. The network core's TEMP peripheral is
39 * sampled periodically; nrf_802154_temperature_get() returns the cached
40 * value and the library is notified via nrf_802154_temperature_changed()
41 * only when it moves, so the hot RSSI path never blocks on a conversion.
42 *
43 * Set NRF_802154_TEMPERATURE_UPDATE_ENABLED to 0 to fall back to a fixed
44 * value (e.g. to leave the TEMP peripheral free for another use).
45 */
46/*---------------------------------------------------------------------------*/
47#include "platform/nrf_802154_temperature.h"
48#include "hal/nrf_temp.h"
49#include "nrf.h"
50
51#include <stdint.h>
52/*---------------------------------------------------------------------------*/
53#ifndef NRF_802154_TEMPERATURE_UPDATE_ENABLED
54#define NRF_802154_TEMPERATURE_UPDATE_ENABLED 1
55#endif
56
57/* Reading [degrees C] used before the first sample completes and whenever
58 * periodic updates are disabled. */
59#ifndef NRF_802154_TEMPERATURE_DEFAULT
60#define NRF_802154_TEMPERATURE_DEFAULT 20
61#endif
62
63#if NRF_802154_TEMPERATURE_UPDATE_ENABLED
64#include "sys/ctimer.h"
65
66/* Re-sample interval. The correction does not need fast updates; one second
67 * matches the default of Nordic's Zephyr port. */
68#ifndef NRF_802154_TEMPERATURE_UPDATE_INTERVAL
69#define NRF_802154_TEMPERATURE_UPDATE_INTERVAL CLOCK_SECOND
70#endif
71
72static struct ctimer update_timer;
73#endif /* NRF_802154_TEMPERATURE_UPDATE_ENABLED */
74
75static int8_t cached_temperature = NRF_802154_TEMPERATURE_DEFAULT;
76/*---------------------------------------------------------------------------*/
77#if NRF_802154_TEMPERATURE_UPDATE_ENABLED
78static int8_t
79temperature_measure(void)
80{
81 int32_t raw;
82
83 /* A single conversion completes in tens of microseconds; this is only
84 * reached from the periodic ctimer (process context), never the radio
85 * hot path, so the short busy-wait does not delay frame handling. */
86 nrf_temp_event_clear(NRF_TEMP, NRF_TEMP_EVENT_DATARDY);
87 nrf_temp_task_trigger(NRF_TEMP, NRF_TEMP_TASK_START);
88 while(!nrf_temp_event_check(NRF_TEMP, NRF_TEMP_EVENT_DATARDY)) {
89 }
90 nrf_temp_event_clear(NRF_TEMP, NRF_TEMP_EVENT_DATARDY);
91 nrf_temp_task_trigger(NRF_TEMP, NRF_TEMP_TASK_STOP);
92
93 /* The result register holds the temperature in 0.25 degree C steps.
94 * Round to the nearest degree instead of truncating toward zero. */
95 raw = nrf_temp_result_get(NRF_TEMP);
96 return (int8_t)((raw >= 0 ? raw + 2 : raw - 2) / 4);
97}
98/*---------------------------------------------------------------------------*/
99static void
100temperature_update(void *ptr)
101{
102 int8_t now = temperature_measure();
103
104 (void)ptr;
105
106 if(now != cached_temperature) {
107 cached_temperature = now;
108 nrf_802154_temperature_changed();
109 }
110
111 ctimer_reset(&update_timer);
112}
113#endif /* NRF_802154_TEMPERATURE_UPDATE_ENABLED */
114/*---------------------------------------------------------------------------*/
115void
116nrf_802154_temperature_init(void)
117{
118#if NRF_802154_TEMPERATURE_UPDATE_ENABLED
119 /* Prime the cache with a real reading, then poll for changes. The initial
120 * sample intentionally does not invoke nrf_802154_temperature_changed():
121 * the library has not cached anything to invalidate yet. */
122 cached_temperature = temperature_measure();
123 ctimer_set(&update_timer, NRF_802154_TEMPERATURE_UPDATE_INTERVAL,
124 temperature_update, NULL);
125#endif
126}
127/*---------------------------------------------------------------------------*/
128void
129nrf_802154_temperature_deinit(void)
130{
131#if NRF_802154_TEMPERATURE_UPDATE_ENABLED
132 ctimer_stop(&update_timer);
133#endif
134}
135/*---------------------------------------------------------------------------*/
136int8_t
137nrf_802154_temperature_get(void)
138{
139 return cached_temperature;
140}
141/*---------------------------------------------------------------------------*/
Header file for the callback timer.
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
Definition ctimer.c:150
void ctimer_reset(struct ctimer *c)
Reset a callback timer with the same interval as was previously set.
Definition ctimer.c:112
static void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition ctimer.h:150