1 /*
2 * Copyright (c) 2017 - 2023, 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 Nordic Semiconductor ASA 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
35 /**
36 * @brief Module that contains calculations of the duration of the 802.15.4 radio driver procedures.
37 *
38 */
39
40 #ifndef NRF_802154_PROCEDURES_DURATION_H_
41 #define NRF_802154_PROCEDURES_DURATION_H_
42
43 #include <stdbool.h>
44 #include <stdint.h>
45 #include "nrfx.h"
46
47 #include "nrf_802154_const.h"
48
49 #define TX_RAMP_UP_TIME 40 // us
50 #define RX_RAMP_UP_TIME 40 // us
51 #define RX_RAMP_DOWN_TIME 0 // us
52 #define MAX_RAMP_DOWN_TIME 6 // us
53 #define RX_TX_TURNAROUND_TIME 20 // us
54
55 #define A_CCA_DURATION_SYMBOLS 8 // sym
56 #define A_TURNAROUND_TIME_SYMBOLS 12 // sym
57 #define A_UNIT_BACKOFF_SYMBOLS 20 // sym
58
59 #define PHY_SYMBOLS_FROM_OCTETS(octets) ((octets) * PHY_SYMBOLS_PER_OCTET)
60 #define PHY_US_TIME_FROM_SYMBOLS(symbols) ((symbols) * PHY_US_PER_SYMBOL)
61
62 #define IMM_ACK_SYMBOLS (PHY_SHR_SYMBOLS + \
63 PHY_SYMBOLS_FROM_OCTETS(IMM_ACK_LENGTH + PHR_SIZE))
64 #define IMM_ACK_DURATION (PHY_US_TIME_FROM_SYMBOLS(IMM_ACK_SYMBOLS))
65
66 #define MAC_IMM_ACK_WAIT_SYMBOLS (A_UNIT_BACKOFF_SYMBOLS + \
67 A_TURNAROUND_TIME_SYMBOLS + \
68 IMM_ACK_SYMBOLS)
69
70 /**@brief Time (in microseconds) necessary to send the longest possible 802.15.4 frame */
71 #define MAX_PHY_FRAME_TIME_US \
72 PHY_US_TIME_FROM_SYMBOLS( \
73 PHY_SHR_SYMBOLS + PHY_SYMBOLS_FROM_OCTETS(PHR_SIZE + MAX_PACKET_SIZE))
74
75 __STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length,
76 bool cca,
77 bool ack_requested);
78
79 __STATIC_INLINE uint16_t nrf_802154_cca_before_tx_duration_get(void);
80
81 __STATIC_INLINE uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ack_requested);
82
83 __STATIC_INLINE uint16_t nrf_802154_cca_duration_get(void);
84
85 #ifndef SUPPRESS_INLINE_IMPLEMENTATION
86
nrf_802154_frame_duration_get(uint8_t psdu_length,bool shr,bool phr)87 __STATIC_INLINE uint16_t nrf_802154_frame_duration_get(uint8_t psdu_length,
88 bool shr,
89 bool phr)
90 {
91 uint16_t us_time = PHY_US_TIME_FROM_SYMBOLS(PHY_SYMBOLS_FROM_OCTETS(psdu_length));
92
93 if (phr)
94 {
95 us_time += PHY_US_TIME_FROM_SYMBOLS(PHY_SYMBOLS_FROM_OCTETS(PHR_SIZE));
96 }
97
98 if (shr)
99 {
100 us_time += PHY_US_TIME_FROM_SYMBOLS(PHY_SHR_SYMBOLS);
101 }
102
103 return us_time;
104 }
105
nrf_802154_tx_duration_get(uint8_t psdu_length,bool cca,bool ack_requested)106 __STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length,
107 bool cca,
108 bool ack_requested)
109 {
110 // ramp down
111 // if CCA: + RX ramp up + CCA + RX ramp down
112 // + TX ramp up + SHR + PHR + PSDU
113 // if ACK: + macAckWaitDuration
114 uint16_t us_time = MAX_RAMP_DOWN_TIME + TX_RAMP_UP_TIME + nrf_802154_frame_duration_get(
115 psdu_length,
116 true,
117 true);
118
119 if (ack_requested)
120 {
121 us_time += PHY_US_TIME_FROM_SYMBOLS(MAC_IMM_ACK_WAIT_SYMBOLS);
122 }
123
124 if (cca)
125 {
126 us_time += RX_RAMP_UP_TIME + RX_RAMP_DOWN_TIME + PHY_US_TIME_FROM_SYMBOLS(
127 A_CCA_DURATION_SYMBOLS);
128 }
129
130 return us_time;
131 }
132
nrf_802154_cca_before_tx_duration_get(void)133 __STATIC_INLINE uint16_t nrf_802154_cca_before_tx_duration_get(void)
134 {
135 // CCA + turnaround time
136 uint16_t us_time = PHY_US_TIME_FROM_SYMBOLS(A_CCA_DURATION_SYMBOLS) + RX_TX_TURNAROUND_TIME;
137
138 return us_time;
139 }
140
141 /**@brief Get the duration of the Ack frame along with turnaround in microseconds. */
nrf_802154_ack_duration_with_turnaround_get(void)142 __STATIC_INLINE uint16_t nrf_802154_ack_duration_with_turnaround_get(void)
143 {
144 // aTurnaroundTime + ACK frame duration
145 return PHY_US_TIME_FROM_SYMBOLS(A_TURNAROUND_TIME_SYMBOLS +
146 PHY_SHR_SYMBOLS +
147 PHY_SYMBOLS_FROM_OCTETS(IMM_ACK_LENGTH + PHR_SIZE));
148 }
149
nrf_802154_rx_duration_get(uint8_t psdu_length,bool ack_requested)150 __STATIC_INLINE uint16_t nrf_802154_rx_duration_get(uint8_t psdu_length, bool ack_requested)
151 {
152 // SHR + PHR + PSDU
153 // if ACK: + aTurnaroundTime + ACK frame duration
154 uint16_t us_time = nrf_802154_frame_duration_get(psdu_length, true, true);
155
156 if (ack_requested)
157 {
158 us_time += nrf_802154_ack_duration_with_turnaround_get();
159 }
160
161 return us_time;
162 }
163
nrf_802154_cca_duration_get(void)164 __STATIC_INLINE uint16_t nrf_802154_cca_duration_get(void)
165 {
166 // ramp down + rx ramp up + CCA
167 uint16_t us_time = MAX_RAMP_DOWN_TIME +
168 RX_RAMP_UP_TIME +
169 PHY_US_TIME_FROM_SYMBOLS(A_CCA_DURATION_SYMBOLS);
170
171 return us_time;
172 }
173
174 #endif /* SUPPRESS_INLINE_IMPLEMENTATION */
175
176 #endif /* NRF_802154_PROCEDURES_DURATION_H_ */
177