Contiki-NG
Loading...
Searching...
No Matches
nrf_802154_platform_hp_timer.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 * High-precision timer for nrf_802154 on the nRF5340 network core.
34 *
35 * Uses TIMER2 at 1 MHz (Contiki-NG rtimer uses TIMER0, the radio uses
36 * TIMER1). Only exercised when frame timestamping is enabled; it is
37 * currently disabled in the project config, but the timer is provided
38 * so the feature can be turned on without further platform work.
39 * Channel layout matches Nordic's upstream HP timer contract.
40 */
41/*---------------------------------------------------------------------------*/
42#include "platform/nrf_802154_hp_timer.h"
43#include "hal/nrf_timer.h"
44#include "nrf.h"
45
46#define HP_TIMER NRF_TIMER2
47
48#define CAPTURE_CC 1
49#define SYNC_CC 2
50#define TIMESTAMP_CC 3
51
52/* 1 MHz tick (1 us resolution). Derive the prescaler from the instance base
53 * clock (16 MHz on the nRF5340) so the value stays correct by construction:
54 * log2(16 MHz / 1 MHz) = 4. */
55#define HP_TIMER_FREQ_HZ 1000000UL
56#define HP_TIMER_PRESCALER NRF_TIMER_PRESCALER_CALCULATE( \
57 NRF_TIMER_BASE_FREQUENCY_GET(HP_TIMER), \
58 HP_TIMER_FREQ_HZ)
59
60static uint32_t unexpected_sync;
61/*---------------------------------------------------------------------------*/
62static inline uint32_t
63timer_time_get(void)
64{
65 nrf_timer_task_trigger(HP_TIMER, (nrf_timer_task_t)NRF_TIMER_TASK_CAPTURE1);
66 return nrf_timer_cc_get(HP_TIMER, (nrf_timer_cc_channel_t)CAPTURE_CC);
67}
68/*---------------------------------------------------------------------------*/
69void
70nrf_802154_hp_timer_init(void)
71{
72 nrf_timer_bit_width_set(HP_TIMER, NRF_TIMER_BIT_WIDTH_32);
73 nrf_timer_prescaler_set(HP_TIMER, HP_TIMER_PRESCALER);
74 nrf_timer_mode_set(HP_TIMER, NRF_TIMER_MODE_TIMER);
75}
76/*---------------------------------------------------------------------------*/
77void
78nrf_802154_hp_timer_deinit(void)
79{
80 nrf_timer_task_trigger(HP_TIMER, NRF_TIMER_TASK_STOP);
81 nrf_timer_task_trigger(HP_TIMER, NRF_TIMER_TASK_CLEAR);
82}
83/*---------------------------------------------------------------------------*/
84void
85nrf_802154_hp_timer_start(void)
86{
87 nrf_timer_task_trigger(HP_TIMER, NRF_TIMER_TASK_START);
88}
89/*---------------------------------------------------------------------------*/
90void
91nrf_802154_hp_timer_stop(void)
92{
93 nrf_timer_task_trigger(HP_TIMER, NRF_TIMER_TASK_STOP);
94 nrf_timer_task_trigger(HP_TIMER, NRF_TIMER_TASK_CLEAR);
95}
96/*---------------------------------------------------------------------------*/
97uint32_t
98nrf_802154_hp_timer_current_time_get(void)
99{
100 return timer_time_get();
101}
102/*---------------------------------------------------------------------------*/
103uint32_t
104nrf_802154_hp_timer_sync_task_get(void)
105{
106 return nrf_timer_task_address_get(HP_TIMER,
107 (nrf_timer_task_t)NRF_TIMER_TASK_CAPTURE2);
108}
109/*---------------------------------------------------------------------------*/
110void
111nrf_802154_hp_timer_sync_prepare(void)
112{
113 uint32_t past_time = timer_time_get() - 1;
114
115 unexpected_sync = past_time;
116 nrf_timer_cc_set(HP_TIMER, (nrf_timer_cc_channel_t)SYNC_CC, past_time);
117}
118/*---------------------------------------------------------------------------*/
119bool
120nrf_802154_hp_timer_sync_time_get(uint32_t *p_timestamp)
121{
122 uint32_t sync_time = nrf_timer_cc_get(HP_TIMER, (nrf_timer_cc_channel_t)SYNC_CC);
123
124 if(sync_time != unexpected_sync) {
125 *p_timestamp = sync_time;
126 return true;
127 }
128
129 return false;
130}
131/*---------------------------------------------------------------------------*/
132uint32_t
133nrf_802154_hp_timer_timestamp_task_get(void)
134{
135 return nrf_timer_task_address_get(HP_TIMER,
136 (nrf_timer_task_t)NRF_TIMER_TASK_CAPTURE3);
137}
138/*---------------------------------------------------------------------------*/
139uint32_t
140nrf_802154_hp_timer_timestamp_get(void)
141{
142 return nrf_timer_cc_get(HP_TIMER, (nrf_timer_cc_channel_t)TIMESTAMP_CC);
143}
144/*---------------------------------------------------------------------------*/