1 /*
2  * Copyright (c) 2018, 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  * @file
37  *   This file implements the nrf 802.15.4 radio driver.
38  *
39  */
40 
41 #define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_APPLICATION
42 
43 #include "nrf_802154.h"
44 
45 #include "nrf_802154_assert.h"
46 #include <stdbool.h>
47 #include <stddef.h>
48 #include <stdint.h>
49 #include <string.h>
50 
51 #include "nrf_802154_config.h"
52 #include "nrf_802154_utils.h"
53 #include "nrf_802154_const.h"
54 #include "nrf_802154_core.h"
55 #include "nrf_802154_critical_section.h"
56 #include "nrf_802154_debug.h"
57 #include "nrf_802154_notification.h"
58 #include "nrf_802154_pib.h"
59 #include "nrf_802154_request.h"
60 #include "nrf_802154_rx_buffer.h"
61 #include "nrf_802154_tx_power.h"
62 #include "nrf_802154_stats.h"
63 #include "hal/nrf_radio.h"
64 #include "platform/nrf_802154_clock.h"
65 #include "platform/nrf_802154_random.h"
66 #include "platform/nrf_802154_temperature.h"
67 #include "rsch/nrf_802154_rsch.h"
68 #include "rsch/nrf_802154_rsch_crit_sect.h"
69 #include "timer/nrf_802154_timer_coord.h"
70 
71 #include "mac_features/nrf_802154_ack_timeout.h"
72 #include "mac_features/nrf_802154_delayed_trx.h"
73 #include "mac_features/nrf_802154_ie_writer.h"
74 #include "mac_features/nrf_802154_ifs.h"
75 #include "mac_features/nrf_802154_security_pib.h"
76 #include "mac_features/ack_generator/nrf_802154_ack_data.h"
77 
78 #include "nrf_802154_sl_ant_div.h"
79 #include "nrf_802154_sl_crit_sect_if.h"
80 #include "nrf_802154_sl_capabilities.h"
81 #include "nrf_802154_sl_timer.h"
82 
83 #if NRF_802154_CARRIER_FUNCTIONS_ENABLED
84 /** Static transmit buffer used by @sa nrf_802154_modulated_carrier function.
85  *
86  * If none of functions using this buffer is called and link time optimization is enabled, this
87  * buffer should be removed by linker.
88  */
89 static uint8_t m_tx_buffer[RAW_PAYLOAD_OFFSET + MAX_PACKET_SIZE];
90 
91 #endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
92 
93 #if NRF_802154_CARRIER_FUNCTIONS_ENABLED
94 /**
95  * @brief Fill the transmit buffer with given data in order to use it with the
96  * modulated carrier functionality.
97  *
98  * @param[in]  p_data   Pointer to array containing modulating data.
99  */
tx_buffer_fill_for_modulated_carrier(const uint8_t * p_data)100 static void tx_buffer_fill_for_modulated_carrier(const uint8_t * p_data)
101 {
102     uint8_t length = p_data[RAW_LENGTH_OFFSET];
103 
104     NRF_802154_ASSERT(length <= MAX_PACKET_SIZE);
105 
106     memcpy(m_tx_buffer, p_data, RAW_PAYLOAD_OFFSET + length);
107 }
108 
109 #endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
110 
are_frame_properties_valid(const nrf_802154_transmitted_frame_props_t * p_props)111 static inline bool are_frame_properties_valid(const nrf_802154_transmitted_frame_props_t * p_props)
112 {
113     return p_props->dynamic_data_is_set || !(p_props->is_secured);
114 }
115 
are_extra_cca_attempts_valid(const nrf_802154_transmit_at_metadata_t * p_data)116 static inline bool are_extra_cca_attempts_valid(const nrf_802154_transmit_at_metadata_t * p_data)
117 {
118     return !p_data->cca || (p_data->extra_cca_attempts < UINT8_MAX);
119 }
120 
nrf_802154_channel_set(uint8_t channel)121 void nrf_802154_channel_set(uint8_t channel)
122 {
123     bool changed = nrf_802154_pib_channel_get() != channel;
124 
125     nrf_802154_pib_channel_set(channel);
126 
127     if (changed)
128     {
129         (void)nrf_802154_request_channel_update(REQ_ORIG_HIGHER_LAYER);
130     }
131 }
132 
nrf_802154_channel_get(void)133 uint8_t nrf_802154_channel_get(void)
134 {
135     return nrf_802154_pib_channel_get();
136 }
137 
nrf_802154_tx_power_set(int8_t power)138 void nrf_802154_tx_power_set(int8_t power)
139 {
140     nrf_802154_pib_tx_power_set(power);
141 }
142 
nrf_802154_tx_power_get(void)143 int8_t nrf_802154_tx_power_get(void)
144 {
145     nrf_802154_fal_tx_power_split_t split_power = {0};
146 
147     return nrf_802154_tx_power_split_pib_power_get(&split_power);
148 }
149 
nrf_802154_coex_rx_request_mode_set(nrf_802154_coex_rx_request_mode_t mode)150 bool nrf_802154_coex_rx_request_mode_set(nrf_802154_coex_rx_request_mode_t mode)
151 {
152     return nrf_802154_pib_coex_rx_request_mode_set(mode);
153 }
154 
nrf_802154_coex_rx_request_mode_get(void)155 nrf_802154_coex_rx_request_mode_t nrf_802154_coex_rx_request_mode_get(void)
156 {
157     return nrf_802154_pib_coex_rx_request_mode_get();
158 }
159 
nrf_802154_coex_tx_request_mode_set(nrf_802154_coex_tx_request_mode_t mode)160 bool nrf_802154_coex_tx_request_mode_set(nrf_802154_coex_tx_request_mode_t mode)
161 {
162     return nrf_802154_pib_coex_tx_request_mode_set(mode);
163 }
164 
nrf_802154_coex_tx_request_mode_get(void)165 nrf_802154_coex_tx_request_mode_t nrf_802154_coex_tx_request_mode_get(void)
166 {
167     return nrf_802154_pib_coex_tx_request_mode_get();
168 }
169 
nrf_802154_temperature_changed(void)170 void nrf_802154_temperature_changed(void)
171 {
172     nrf_802154_request_cca_cfg_update();
173 }
174 
nrf_802154_pan_id_set(const uint8_t * p_pan_id)175 void nrf_802154_pan_id_set(const uint8_t * p_pan_id)
176 {
177     nrf_802154_pib_pan_id_set(p_pan_id);
178 }
179 
nrf_802154_extended_address_set(const uint8_t * p_extended_address)180 void nrf_802154_extended_address_set(const uint8_t * p_extended_address)
181 {
182     nrf_802154_pib_extended_address_set(p_extended_address);
183 }
184 
nrf_802154_short_address_set(const uint8_t * p_short_address)185 void nrf_802154_short_address_set(const uint8_t * p_short_address)
186 {
187     nrf_802154_pib_short_address_set(p_short_address);
188 }
189 
nrf_802154_init(void)190 void nrf_802154_init(void)
191 {
192     static const nrf_802154_sl_crit_sect_interface_t crit_sect_int =
193     {
194         .enter = nrf_802154_critical_section_enter,
195         .exit  = nrf_802154_critical_section_exit
196     };
197 
198     nrf_802154_ack_data_init();
199     nrf_802154_core_init();
200     nrf_802154_clock_init();
201     nrf_802154_critical_section_init();
202     nrf_802154_sl_crit_sect_init(&crit_sect_int);
203     nrf_802154_debug_init();
204     nrf_802154_notification_init();
205     nrf_802154_pib_init();
206     nrf_802154_security_pib_init();
207     nrf_802154_sl_timer_module_init();
208     nrf_802154_random_init();
209     nrf_802154_request_init();
210     nrf_802154_rsch_crit_sect_init();
211     nrf_802154_rsch_init();
212     nrf_802154_rx_buffer_init();
213     nrf_802154_temperature_init();
214     nrf_802154_timer_coord_init();
215 #if NRF_802154_ACK_TIMEOUT_ENABLED
216     nrf_802154_ack_timeout_init();
217 #endif
218 #if NRF_802154_DELAYED_TRX_ENABLED
219     nrf_802154_delayed_trx_init();
220 #endif
221 #if NRF_802154_IFS_ENABLED
222     nrf_802154_ifs_init();
223 #endif
224 }
225 
nrf_802154_deinit(void)226 void nrf_802154_deinit(void)
227 {
228     nrf_802154_timer_coord_uninit();
229     nrf_802154_temperature_deinit();
230     nrf_802154_rsch_uninit();
231     nrf_802154_random_deinit();
232     nrf_802154_security_pib_deinit();
233     nrf_802154_sl_timer_module_uninit();
234     nrf_802154_clock_deinit();
235     nrf_802154_core_deinit();
236 #if NRF_802154_ACK_TIMEOUT_ENABLED
237     nrf_802154_ack_timeout_deinit();
238 #endif
239 #if NRF_802154_DELAYED_TRX_ENABLED
240     nrf_802154_delayed_trx_deinit();
241 #endif
242 #if NRF_802154_IFS_ENABLED
243     nrf_802154_ifs_deinit();
244 #endif
245 }
246 
nrf_802154_antenna_diversity_rx_mode_set(nrf_802154_sl_ant_div_mode_t mode)247 bool nrf_802154_antenna_diversity_rx_mode_set(nrf_802154_sl_ant_div_mode_t mode)
248 {
249     bool result = false;
250 
251 #if defined(RADIO_INTENSET_SYNC_Msk)
252     result = nrf_802154_sl_ant_div_cfg_mode_set(NRF_802154_SL_ANT_DIV_OP_RX, mode);
253 #endif
254 
255     if (result)
256     {
257         nrf_802154_request_antenna_update();
258     }
259 
260     return result;
261 }
262 
nrf_802154_antenna_diversity_rx_mode_get(void)263 nrf_802154_sl_ant_div_mode_t nrf_802154_antenna_diversity_rx_mode_get(void)
264 {
265     return nrf_802154_sl_ant_div_cfg_mode_get(NRF_802154_SL_ANT_DIV_OP_RX);
266 }
267 
nrf_802154_antenna_diversity_tx_mode_set(nrf_802154_sl_ant_div_mode_t mode)268 bool nrf_802154_antenna_diversity_tx_mode_set(nrf_802154_sl_ant_div_mode_t mode)
269 {
270     bool result = false;
271 
272 #if defined(RADIO_INTENSET_SYNC_Msk)
273     result = nrf_802154_sl_ant_div_cfg_mode_set(NRF_802154_SL_ANT_DIV_OP_TX, mode);
274 #endif
275 
276     if (result)
277     {
278         nrf_802154_request_antenna_update();
279     }
280 
281     return result;
282 }
283 
nrf_802154_antenna_diversity_tx_mode_get(void)284 nrf_802154_sl_ant_div_mode_t nrf_802154_antenna_diversity_tx_mode_get(void)
285 {
286     return nrf_802154_sl_ant_div_cfg_mode_get(NRF_802154_SL_ANT_DIV_OP_TX);
287 }
288 
nrf_802154_antenna_diversity_rx_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna)289 bool nrf_802154_antenna_diversity_rx_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna)
290 {
291     bool result =
292         nrf_802154_sl_ant_div_cfg_antenna_set(NRF_802154_SL_ANT_DIV_OP_RX, antenna);
293     bool is_manual_mode = nrf_802154_sl_ant_div_cfg_mode_get(NRF_802154_SL_ANT_DIV_OP_RX) ==
294                           NRF_802154_SL_ANT_DIV_MODE_MANUAL;
295 
296     if (result && is_manual_mode)
297     {
298         nrf_802154_request_antenna_update();
299     }
300 
301     return result;
302 }
303 
nrf_802154_antenna_diversity_rx_antenna_get(void)304 nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_rx_antenna_get(void)
305 {
306     return nrf_802154_sl_ant_div_cfg_antenna_get(NRF_802154_SL_ANT_DIV_OP_RX);
307 }
308 
nrf_802154_antenna_diversity_tx_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna)309 bool nrf_802154_antenna_diversity_tx_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna)
310 {
311     bool result =
312         nrf_802154_sl_ant_div_cfg_antenna_set(NRF_802154_SL_ANT_DIV_OP_TX, antenna);
313     bool is_manual_mode = nrf_802154_sl_ant_div_cfg_mode_get(NRF_802154_SL_ANT_DIV_OP_TX) ==
314                           NRF_802154_SL_ANT_DIV_MODE_MANUAL;
315 
316     if (result && is_manual_mode)
317     {
318         nrf_802154_request_antenna_update();
319     }
320 
321     return result;
322 }
323 
nrf_802154_antenna_diversity_tx_antenna_get(void)324 nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_tx_antenna_get(void)
325 {
326     return nrf_802154_sl_ant_div_cfg_antenna_get(NRF_802154_SL_ANT_DIV_OP_TX);
327 }
328 
nrf_802154_antenna_diversity_last_rx_best_antenna_get(void)329 nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_last_rx_best_antenna_get(void)
330 {
331     return nrf_802154_sl_ant_div_last_rx_best_antenna_get();
332 }
333 
nrf_802154_antenna_diversity_config_set(const nrf_802154_sl_ant_div_cfg_t * p_cfg)334 void nrf_802154_antenna_diversity_config_set(const nrf_802154_sl_ant_div_cfg_t * p_cfg)
335 {
336 #if defined(RADIO_INTENSET_SYNC_Msk)
337     nrf_802154_sl_ant_div_cfg_set(p_cfg);
338 #endif
339 }
340 
nrf_802154_antenna_diversity_config_get(nrf_802154_sl_ant_div_cfg_t * p_cfg)341 bool nrf_802154_antenna_diversity_config_get(nrf_802154_sl_ant_div_cfg_t * p_cfg)
342 {
343     return nrf_802154_sl_ant_div_cfg_get(p_cfg);
344 }
345 
nrf_802154_antenna_diversity_init(void)346 bool nrf_802154_antenna_diversity_init(void)
347 {
348     return nrf_802154_sl_ant_div_init();
349 }
350 
nrf_802154_antenna_diversity_timer_irq_handler(void)351 void nrf_802154_antenna_diversity_timer_irq_handler(void)
352 {
353 #if defined(RADIO_INTENSET_SYNC_Msk)
354     nrf_802154_sl_ant_div_timer_irq_handle();
355 #endif
356 }
357 
nrf_802154_state_get(void)358 nrf_802154_state_t nrf_802154_state_get(void)
359 {
360     switch (nrf_802154_core_state_get())
361     {
362         case RADIO_STATE_SLEEP:
363         case RADIO_STATE_FALLING_ASLEEP:
364             return NRF_802154_STATE_SLEEP;
365 
366         case RADIO_STATE_RX:
367         case RADIO_STATE_TX_ACK:
368             return NRF_802154_STATE_RECEIVE;
369 
370         case RADIO_STATE_CCA_TX:
371         case RADIO_STATE_TX:
372         case RADIO_STATE_RX_ACK:
373             return NRF_802154_STATE_TRANSMIT;
374 
375         case RADIO_STATE_ED:
376             return NRF_802154_STATE_ENERGY_DETECTION;
377 
378         case RADIO_STATE_CCA:
379             return NRF_802154_STATE_CCA;
380 
381 #if NRF_802154_CARRIER_FUNCTIONS_ENABLED
382 
383         case RADIO_STATE_CONTINUOUS_CARRIER:
384             return NRF_802154_STATE_CONTINUOUS_CARRIER;
385 
386         case RADIO_STATE_MODULATED_CARRIER:
387             return NRF_802154_STATE_MODULATED_CARRIER;
388 #endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
389 
390     }
391 
392     return NRF_802154_STATE_INVALID;
393 }
394 
nrf_802154_sleep(void)395 bool nrf_802154_sleep(void)
396 {
397     bool result;
398 
399     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
400 
401     result = nrf_802154_request_sleep(NRF_802154_TERM_802154);
402 
403     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
404 
405     return result;
406 }
407 
nrf_802154_sleep_if_idle(void)408 nrf_802154_sleep_error_t nrf_802154_sleep_if_idle(void)
409 {
410     nrf_802154_sleep_error_t result;
411 
412     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
413 
414     result =
415         nrf_802154_request_sleep(NRF_802154_TERM_NONE) ? NRF_802154_SLEEP_ERROR_NONE :
416         NRF_802154_SLEEP_ERROR_BUSY;
417 
418     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
419 
420     return result;
421 }
422 
nrf_802154_receive(void)423 bool nrf_802154_receive(void)
424 {
425     bool result;
426 
427     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
428 
429     result = nrf_802154_request_receive(NRF_802154_TERM_802154,
430                                         REQ_ORIG_HIGHER_LAYER,
431                                         NULL,
432                                         true,
433                                         NRF_802154_RESERVED_IMM_RX_WINDOW_ID);
434 
435     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
436     return result;
437 }
438 
nrf_802154_transmit_raw(uint8_t * p_data,const nrf_802154_transmit_metadata_t * p_metadata)439 bool nrf_802154_transmit_raw(uint8_t                              * p_data,
440                              const nrf_802154_transmit_metadata_t * p_metadata)
441 {
442     bool    result;
443     uint8_t channel;
444 
445     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
446 
447     if (p_metadata == NULL)
448     {
449         static const nrf_802154_transmit_metadata_t metadata_default =
450         {
451             .frame_props = NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT,
452             .cca         = true,
453             .tx_power    = {.use_metadata_value = false},
454             .tx_channel  = {.use_metadata_value = false}
455         };
456 
457         p_metadata = &metadata_default;
458     }
459 
460     channel =
461         p_metadata->tx_channel.use_metadata_value ? p_metadata->tx_channel.channel :
462         nrf_802154_pib_channel_get();
463 
464     nrf_802154_transmit_params_t params =
465     {
466         .frame_props        = p_metadata->frame_props,
467         .tx_power           = {0},
468         .channel            = channel,
469         .cca                = p_metadata->cca,
470         .immediate          = false,
471         .extra_cca_attempts = 0U,
472     };
473 
474     (void)nrf_802154_tx_power_convert_metadata_to_tx_power_split(channel,
475                                                                  p_metadata->tx_power,
476                                                                  &params.tx_power);
477 
478     result = are_frame_properties_valid(&params.frame_props);
479     if (result)
480     {
481         result = nrf_802154_request_transmit(NRF_802154_TERM_NONE,
482                                              REQ_ORIG_HIGHER_LAYER,
483                                              p_data,
484                                              &params,
485                                              NULL);
486     }
487 
488     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
489     return result;
490 }
491 
492 #if NRF_802154_DELAYED_TRX_ENABLED
nrf_802154_transmit_raw_at(uint8_t * p_data,uint64_t tx_time,const nrf_802154_transmit_at_metadata_t * p_metadata)493 bool nrf_802154_transmit_raw_at(uint8_t                                 * p_data,
494                                 uint64_t                                  tx_time,
495                                 const nrf_802154_transmit_at_metadata_t * p_metadata)
496 {
497     bool                              result;
498     nrf_802154_transmit_at_metadata_t metadata_default =
499     {
500         .frame_props        = NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT,
501         .cca                = true,
502         .tx_power           = {.use_metadata_value = false},
503         .extra_cca_attempts = 0,
504     };
505 
506     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
507 
508     if (p_metadata == NULL)
509     {
510         metadata_default.channel = nrf_802154_channel_get();
511         p_metadata               = &metadata_default;
512     }
513 
514     result = are_frame_properties_valid(&p_metadata->frame_props) &&
515              are_extra_cca_attempts_valid(p_metadata);
516     if (result)
517     {
518         result = nrf_802154_request_transmit_raw_at(p_data, tx_time, p_metadata);
519     }
520 
521     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
522     return result;
523 }
524 
nrf_802154_transmit_at_cancel(void)525 bool nrf_802154_transmit_at_cancel(void)
526 {
527     bool result;
528 
529     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
530 
531     result = nrf_802154_request_transmit_at_cancel();
532 
533     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
534     return result;
535 }
536 
nrf_802154_receive_at(uint64_t rx_time,uint32_t timeout,uint8_t channel,uint32_t id)537 bool nrf_802154_receive_at(uint64_t rx_time,
538                            uint32_t timeout,
539                            uint8_t  channel,
540                            uint32_t id)
541 {
542     bool result;
543 
544     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
545 
546     result = nrf_802154_request_receive_at(rx_time, timeout, channel, id);
547 
548     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
549     return result;
550 }
551 
nrf_802154_receive_at_cancel(uint32_t id)552 bool nrf_802154_receive_at_cancel(uint32_t id)
553 {
554     bool result;
555 
556     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
557 
558     result = nrf_802154_request_receive_at_cancel(id);
559 
560     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
561     return result;
562 }
563 
564 #endif // NRF_802154_DELAYED_TRX_ENABLED
565 
nrf_802154_energy_detection(uint32_t time_us)566 bool nrf_802154_energy_detection(uint32_t time_us)
567 {
568     bool result;
569 
570     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
571 
572     result = nrf_802154_request_energy_detection(NRF_802154_TERM_NONE, time_us);
573 
574     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
575     return result;
576 }
577 
nrf_802154_cca(void)578 bool nrf_802154_cca(void)
579 {
580     bool result;
581 
582     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
583 
584     result = nrf_802154_request_cca(NRF_802154_TERM_NONE);
585 
586     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
587     return result;
588 }
589 
590 #if NRF_802154_CARRIER_FUNCTIONS_ENABLED
591 
nrf_802154_continuous_carrier(void)592 bool nrf_802154_continuous_carrier(void)
593 {
594     bool result;
595 
596     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
597 
598     result = nrf_802154_request_continuous_carrier(NRF_802154_TERM_NONE);
599 
600     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
601     return result;
602 }
603 
nrf_802154_modulated_carrier(const uint8_t * p_data)604 bool nrf_802154_modulated_carrier(const uint8_t * p_data)
605 {
606     bool result;
607 
608     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
609 
610     tx_buffer_fill_for_modulated_carrier(p_data);
611 
612     result = nrf_802154_request_modulated_carrier(NRF_802154_TERM_NONE, m_tx_buffer);
613 
614     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
615     return result;
616 }
617 
618 #endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
619 
nrf_802154_buffer_free_raw(uint8_t * p_data)620 void nrf_802154_buffer_free_raw(uint8_t * p_data)
621 {
622     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
623 
624     bool          result;
625     rx_buffer_t * p_buffer = (rx_buffer_t *)p_data;
626 
627     NRF_802154_ASSERT(p_buffer->free == false);
628     (void)p_buffer;
629 
630     result = nrf_802154_request_buffer_free(p_data);
631     NRF_802154_ASSERT(result);
632     (void)result;
633 
634     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
635 }
636 
nrf_802154_buffer_free_immediately_raw(uint8_t * p_data)637 bool nrf_802154_buffer_free_immediately_raw(uint8_t * p_data)
638 {
639     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
640 
641     bool          result;
642     rx_buffer_t * p_buffer = (rx_buffer_t *)p_data;
643 
644     NRF_802154_ASSERT(p_buffer->free == false);
645     (void)p_buffer;
646 
647     result = nrf_802154_request_buffer_free(p_data);
648 
649     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
650     return result;
651 }
652 
nrf_802154_rssi_measure_begin(void)653 bool nrf_802154_rssi_measure_begin(void)
654 {
655     return nrf_802154_request_rssi_measure();
656 }
657 
nrf_802154_rssi_last_get(void)658 int8_t nrf_802154_rssi_last_get(void)
659 {
660     int8_t result = 0;
661 
662     if (!nrf_802154_request_rssi_measurement_get(&result))
663     {
664         result = NRF_802154_RSSI_INVALID;
665     }
666 
667     return result;
668 }
669 
nrf_802154_promiscuous_get(void)670 bool nrf_802154_promiscuous_get(void)
671 {
672     return nrf_802154_pib_promiscuous_get();
673 }
674 
nrf_802154_promiscuous_set(bool enabled)675 void nrf_802154_promiscuous_set(bool enabled)
676 {
677     nrf_802154_pib_promiscuous_set(enabled);
678 }
679 
nrf_802154_rx_on_when_idle_set(bool enabled)680 void nrf_802154_rx_on_when_idle_set(bool enabled)
681 {
682     nrf_802154_pib_rx_on_when_idle_set(enabled);
683 }
684 
nrf_802154_auto_ack_set(bool enabled)685 void nrf_802154_auto_ack_set(bool enabled)
686 {
687     nrf_802154_pib_auto_ack_set(enabled);
688 }
689 
nrf_802154_auto_ack_get(void)690 bool nrf_802154_auto_ack_get(void)
691 {
692     return nrf_802154_pib_auto_ack_get();
693 }
694 
nrf_802154_pan_coord_get(void)695 bool nrf_802154_pan_coord_get(void)
696 {
697     return nrf_802154_pib_pan_coord_get();
698 }
699 
nrf_802154_pan_coord_set(bool enabled)700 void nrf_802154_pan_coord_set(bool enabled)
701 {
702     nrf_802154_pib_pan_coord_set(enabled);
703 }
704 
nrf_802154_src_addr_matching_method_set(nrf_802154_src_addr_match_t match_method)705 void nrf_802154_src_addr_matching_method_set(nrf_802154_src_addr_match_t match_method)
706 {
707     nrf_802154_ack_data_src_addr_matching_method_set(match_method);
708 }
709 
nrf_802154_ack_data_set(const uint8_t * p_addr,bool extended,const void * p_data,uint16_t length,nrf_802154_ack_data_t data_type)710 bool nrf_802154_ack_data_set(const uint8_t       * p_addr,
711                              bool                  extended,
712                              const void          * p_data,
713                              uint16_t              length,
714                              nrf_802154_ack_data_t data_type)
715 {
716     return nrf_802154_ack_data_for_addr_set(p_addr, extended, data_type, p_data, length);
717 }
718 
nrf_802154_ack_data_clear(const uint8_t * p_addr,bool extended,nrf_802154_ack_data_t data_type)719 bool nrf_802154_ack_data_clear(const uint8_t       * p_addr,
720                                bool                  extended,
721                                nrf_802154_ack_data_t data_type)
722 {
723     return nrf_802154_ack_data_for_addr_clear(p_addr, extended, data_type);
724 }
725 
nrf_802154_ack_data_remove_all(bool extended,nrf_802154_ack_data_t data_type)726 void nrf_802154_ack_data_remove_all(bool extended, nrf_802154_ack_data_t data_type)
727 {
728     nrf_802154_ack_data_reset(extended, data_type);
729 }
730 
nrf_802154_auto_pending_bit_set(bool enabled)731 void nrf_802154_auto_pending_bit_set(bool enabled)
732 {
733     nrf_802154_ack_data_enable(enabled);
734 }
735 
nrf_802154_pending_bit_for_addr_set(const uint8_t * p_addr,bool extended)736 bool nrf_802154_pending_bit_for_addr_set(const uint8_t * p_addr, bool extended)
737 {
738     return nrf_802154_ack_data_for_addr_set(p_addr,
739                                             extended,
740                                             NRF_802154_ACK_DATA_PENDING_BIT,
741                                             NULL,
742                                             0);
743 }
744 
nrf_802154_pending_bit_for_addr_clear(const uint8_t * p_addr,bool extended)745 bool nrf_802154_pending_bit_for_addr_clear(const uint8_t * p_addr, bool extended)
746 {
747     return nrf_802154_ack_data_for_addr_clear(p_addr, extended, NRF_802154_ACK_DATA_PENDING_BIT);
748 }
749 
nrf_802154_pending_bit_for_addr_reset(bool extended)750 void nrf_802154_pending_bit_for_addr_reset(bool extended)
751 {
752     nrf_802154_ack_data_reset(extended, NRF_802154_ACK_DATA_PENDING_BIT);
753 }
754 
nrf_802154_cca_cfg_set(const nrf_802154_cca_cfg_t * p_cca_cfg)755 void nrf_802154_cca_cfg_set(const nrf_802154_cca_cfg_t * p_cca_cfg)
756 {
757     nrf_802154_pib_cca_cfg_set(p_cca_cfg);
758 
759     nrf_802154_request_cca_cfg_update();
760 }
761 
nrf_802154_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg)762 void nrf_802154_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg)
763 {
764     nrf_802154_pib_cca_cfg_get(p_cca_cfg);
765 }
766 
767 #if NRF_802154_CSMA_CA_ENABLED
768 
nrf_802154_transmit_csma_ca_raw(uint8_t * p_data,const nrf_802154_transmit_csma_ca_metadata_t * p_metadata)769 bool nrf_802154_transmit_csma_ca_raw(uint8_t                                      * p_data,
770                                      const nrf_802154_transmit_csma_ca_metadata_t * p_metadata)
771 {
772     bool result;
773 
774     nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW);
775 
776     if (p_metadata == NULL)
777     {
778         static const nrf_802154_transmit_csma_ca_metadata_t metadata_default =
779         {
780             .frame_props = NRF_802154_TRANSMITTED_FRAME_PROPS_DEFAULT_INIT,
781             .tx_power    = {.use_metadata_value = false},
782             .tx_channel  = {.use_metadata_value = false}
783         };
784 
785         p_metadata = &metadata_default;
786     }
787 
788     result = are_frame_properties_valid(&p_metadata->frame_props);
789     if (result)
790     {
791         result = nrf_802154_request_csma_ca_start(p_data, p_metadata);
792     }
793 
794     nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW);
795     return result;
796 }
797 
nrf_802154_csma_ca_min_be_set(uint8_t min_be)798 bool nrf_802154_csma_ca_min_be_set(uint8_t min_be)
799 {
800     return nrf_802154_pib_csmaca_min_be_set(min_be);
801 }
802 
nrf_802154_csma_ca_min_be_get(void)803 uint8_t nrf_802154_csma_ca_min_be_get(void)
804 {
805     return nrf_802154_pib_csmaca_min_be_get();
806 }
807 
nrf_802154_csma_ca_max_be_set(uint8_t max_be)808 bool nrf_802154_csma_ca_max_be_set(uint8_t max_be)
809 {
810     return nrf_802154_pib_csmaca_max_be_set(max_be);
811 }
812 
nrf_802154_csma_ca_max_be_get(void)813 uint8_t nrf_802154_csma_ca_max_be_get(void)
814 {
815     return nrf_802154_pib_csmaca_max_be_get();
816 }
817 
nrf_802154_csma_ca_max_backoffs_set(uint8_t max_backoffs)818 void nrf_802154_csma_ca_max_backoffs_set(uint8_t max_backoffs)
819 {
820     nrf_802154_pib_csmaca_max_backoffs_set(max_backoffs);
821 }
822 
nrf_802154_csma_ca_max_backoffs_get(void)823 uint8_t nrf_802154_csma_ca_max_backoffs_get(void)
824 {
825     return nrf_802154_pib_csmaca_max_backoffs_get();
826 }
827 
828 #endif // NRF_802154_CSMA_CA_ENABLED
829 
830 #if NRF_802154_ACK_TIMEOUT_ENABLED
831 
nrf_802154_ack_timeout_set(uint32_t time)832 void nrf_802154_ack_timeout_set(uint32_t time)
833 {
834     nrf_802154_ack_timeout_time_set(time);
835 }
836 
837 #endif // NRF_802154_ACK_TIMEOUT_ENABLED
838 
839 #if NRF_802154_IFS_ENABLED
840 
nrf_802154_ifs_mode_get(void)841 nrf_802154_ifs_mode_t nrf_802154_ifs_mode_get(void)
842 {
843     return nrf_802154_pib_ifs_mode_get();
844 }
845 
nrf_802154_ifs_mode_set(nrf_802154_ifs_mode_t mode)846 bool nrf_802154_ifs_mode_set(nrf_802154_ifs_mode_t mode)
847 {
848     return nrf_802154_pib_ifs_mode_set(mode);
849 }
850 
nrf_802154_ifs_min_sifs_period_get(void)851 uint16_t nrf_802154_ifs_min_sifs_period_get(void)
852 {
853     return nrf_802154_pib_ifs_min_sifs_period_get();
854 }
855 
nrf_802154_ifs_min_sifs_period_set(uint16_t period)856 void nrf_802154_ifs_min_sifs_period_set(uint16_t period)
857 {
858     nrf_802154_pib_ifs_min_sifs_period_set(period);
859 }
860 
nrf_802154_ifs_min_lifs_period_get(void)861 uint16_t nrf_802154_ifs_min_lifs_period_get(void)
862 {
863     return nrf_802154_pib_ifs_min_lifs_period_get();
864 }
865 
nrf_802154_ifs_min_lifs_period_set(uint16_t period)866 void nrf_802154_ifs_min_lifs_period_set(uint16_t period)
867 {
868     nrf_802154_pib_ifs_min_lifs_period_set(period);
869 }
870 
871 #endif // NRF_802154_IFS_ENABLED
872 
nrf_802154_capabilities_get(void)873 nrf_802154_capabilities_t nrf_802154_capabilities_get(void)
874 {
875     nrf_802154_capabilities_t    caps_drv = 0UL;
876     nrf_802154_sl_capabilities_t caps_sl  = nrf_802154_sl_capabilities_get();
877 
878     /* Capabilities of the Service Layer depend on the version of it linked in,
879      * hence require run-time probing. */
880     caps_drv |= (NRF_802154_SL_CAPABILITY_CSMA & caps_sl) ?
881                 NRF_802154_CAPABILITY_CSMA : 0UL;
882     caps_drv |= (NRF_802154_SL_CAPABILITY_DELAYED_TX & caps_sl) ?
883                 NRF_802154_CAPABILITY_DELAYED_TX : 0UL;
884     caps_drv |= (NRF_802154_SL_CAPABILITY_DELAYED_RX & caps_sl) ?
885                 NRF_802154_CAPABILITY_DELAYED_RX : 0UL;
886     caps_drv |= (NRF_802154_SL_CAPABILITY_ANT_DIVERSITY & caps_sl) ?
887                 NRF_802154_CAPABILITY_ANT_DIVERSITY : 0UL;
888     caps_drv |= (NRF_802154_SL_CAPABILITY_TIMESTAMP & caps_sl) ?
889                 NRF_802154_CAPABILITY_TIMESTAMP : 0UL;
890 
891     /* Some Radio Driver capabilities are configured at compile time. */
892     caps_drv |= (NRF_802154_ACK_TIMEOUT_ENABLED ?
893                  NRF_802154_CAPABILITY_ACK_TIMEOUT : 0UL);
894 
895     caps_drv |= ((NRF_802154_SECURITY_WRITER_ENABLED && NRF_802154_ENCRYPTION_ENABLED) ?
896                  NRF_802154_CAPABILITY_SECURITY : 0UL);
897 
898     /* Both IFS and ACK Timeout features require SL timer, however
899      * using them both at the same time requires that SL is able to schedule
900      * several timers simultaneously.
901      *
902      * ACK Timeout capability takes precedence over IFS if only one timer
903      * can be scheduled because there is no known usecase for IFS without ACK Timeout,
904      * and this configuration would require additional testing. If such usecase emerges,
905      * this logic should be updated.
906      */
907     if (NRF_802154_SL_CAPABILITY_MULTITIMER & caps_sl)
908     {
909         caps_drv |= (NRF_802154_IFS_ENABLED ?
910                      NRF_802154_CAPABILITY_IFS : 0UL);
911     }
912 
913     return caps_drv;
914 }
915 
nrf_802154_time_get(void)916 uint64_t nrf_802154_time_get(void)
917 {
918     return nrf_802154_sl_timer_current_time_get();
919 }
920 
nrf_802154_security_global_frame_counter_set(uint32_t frame_counter)921 void nrf_802154_security_global_frame_counter_set(uint32_t frame_counter)
922 {
923     nrf_802154_security_pib_global_frame_counter_set(frame_counter);
924 }
925 
nrf_802154_security_global_frame_counter_set_if_larger(uint32_t frame_counter)926 void nrf_802154_security_global_frame_counter_set_if_larger(uint32_t frame_counter)
927 {
928     nrf_802154_security_pib_global_frame_counter_set_if_larger(frame_counter);
929 }
930 
nrf_802154_security_key_store(nrf_802154_key_t * p_key)931 nrf_802154_security_error_t nrf_802154_security_key_store(nrf_802154_key_t * p_key)
932 {
933     return nrf_802154_security_pib_key_store(p_key);
934 }
935 
nrf_802154_security_key_remove(nrf_802154_key_id_t * p_id)936 nrf_802154_security_error_t nrf_802154_security_key_remove(nrf_802154_key_id_t * p_id)
937 {
938     return nrf_802154_security_pib_key_remove(p_id);
939 }
940 
nrf_802154_security_key_remove_all(void)941 void nrf_802154_security_key_remove_all(void)
942 {
943     nrf_802154_security_pib_key_remove_all();
944 }
945 
946 #if NRF_802154_DELAYED_TRX_ENABLED && NRF_802154_IE_WRITER_ENABLED
947 
nrf_802154_csl_writer_period_set(uint16_t period)948 void nrf_802154_csl_writer_period_set(uint16_t period)
949 {
950     nrf_802154_ie_writer_csl_period_set(period);
951 }
952 
nrf_802154_csl_writer_anchor_time_set(uint64_t anchor_time)953 void nrf_802154_csl_writer_anchor_time_set(uint64_t anchor_time)
954 {
955     nrf_802154_ie_writer_csl_anchor_time_set(anchor_time);
956 }
957 
nrf_802154_cst_writer_period_set(uint16_t period)958 void nrf_802154_cst_writer_period_set(uint16_t period)
959 {
960     nrf_802154_ie_writer_cst_period_set(period);
961 }
962 
nrf_802154_cst_writer_anchor_time_set(uint64_t anchor_time)963 void nrf_802154_cst_writer_anchor_time_set(uint64_t anchor_time)
964 {
965     nrf_802154_ie_writer_cst_anchor_time_set(anchor_time);
966 }
967 
968 #endif
969 
nrf_802154_custom_part_of_radio_init(void)970 __WEAK void nrf_802154_custom_part_of_radio_init(void)
971 {
972     // Intentionally empty
973 }
974 
nrf_802154_tx_ack_started(const uint8_t * p_data)975 __WEAK void nrf_802154_tx_ack_started(const uint8_t * p_data)
976 {
977     (void)p_data;
978 }
979 
nrf_802154_received_raw(uint8_t * p_data,int8_t power,uint8_t lqi)980 __WEAK void nrf_802154_received_raw(uint8_t * p_data, int8_t power, uint8_t lqi)
981 {
982     uint64_t timestamp;
983 
984     nrf_802154_stat_timestamp_read(&timestamp, last_rx_end_timestamp);
985 
986     nrf_802154_received_timestamp_raw(p_data,
987                                       power,
988                                       lqi,
989                                       timestamp);
990 }
991 
nrf_802154_received_timestamp_raw(uint8_t * p_data,int8_t power,uint8_t lqi,uint64_t time)992 __WEAK void nrf_802154_received_timestamp_raw(uint8_t * p_data,
993                                               int8_t    power,
994                                               uint8_t   lqi,
995                                               uint64_t  time)
996 {
997     (void)power;
998     (void)lqi;
999     (void)time;
1000 
1001     nrf_802154_buffer_free_raw(p_data);
1002 }
1003 
nrf_802154_receive_failed(nrf_802154_rx_error_t error,uint32_t id)1004 __WEAK void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id)
1005 {
1006     (void)error;
1007     (void)id;
1008 }
1009 
nrf_802154_tx_started(const uint8_t * p_frame)1010 __WEAK void nrf_802154_tx_started(const uint8_t * p_frame)
1011 {
1012     (void)p_frame;
1013 }
1014 
nrf_802154_transmitted_raw(uint8_t * p_frame,const nrf_802154_transmit_done_metadata_t * p_metadata)1015 __WEAK void nrf_802154_transmitted_raw(uint8_t                                   * p_frame,
1016                                        const nrf_802154_transmit_done_metadata_t * p_metadata)
1017 {
1018     (void)p_frame;
1019 
1020     uint8_t * p_ack = p_metadata->data.transmitted.p_ack;
1021 
1022     if (p_ack != NULL)
1023     {
1024         nrf_802154_buffer_free_raw(p_ack);
1025     }
1026 }
1027 
nrf_802154_transmit_failed(uint8_t * p_frame,nrf_802154_tx_error_t error,const nrf_802154_transmit_done_metadata_t * p_metadata)1028 __WEAK void nrf_802154_transmit_failed(uint8_t                                   * p_frame,
1029                                        nrf_802154_tx_error_t                       error,
1030                                        const nrf_802154_transmit_done_metadata_t * p_metadata)
1031 {
1032     (void)p_frame;
1033     (void)error;
1034     (void)p_metadata;
1035 }
1036 
nrf_802154_energy_detected(const nrf_802154_energy_detected_t * p_result)1037 __WEAK void nrf_802154_energy_detected(const nrf_802154_energy_detected_t * p_result)
1038 {
1039     (void)p_result;
1040 }
1041 
nrf_802154_energy_detection_failed(nrf_802154_ed_error_t error)1042 __WEAK void nrf_802154_energy_detection_failed(nrf_802154_ed_error_t error)
1043 {
1044     (void)error;
1045 }
1046 
nrf_802154_cca_done(bool channel_free)1047 __WEAK void nrf_802154_cca_done(bool channel_free)
1048 {
1049     (void)channel_free;
1050 }
1051 
nrf_802154_cca_failed(nrf_802154_cca_error_t error)1052 __WEAK void nrf_802154_cca_failed(nrf_802154_cca_error_t error)
1053 {
1054     (void)error;
1055 }
1056 
1057 #if NRF_802154_TEST_MODES_ENABLED
1058 
nrf_802154_test_mode_csmaca_backoff_get(void)1059 nrf_802154_test_mode_csmaca_backoff_t nrf_802154_test_mode_csmaca_backoff_get(void)
1060 {
1061     return nrf_802154_pib_test_mode_csmaca_backoff_get();
1062 }
1063 
nrf_802154_test_mode_csmaca_backoff_set(nrf_802154_test_mode_csmaca_backoff_t value)1064 void nrf_802154_test_mode_csmaca_backoff_set(nrf_802154_test_mode_csmaca_backoff_t value)
1065 {
1066     nrf_802154_pib_test_mode_csmaca_backoff_set(value);
1067 }
1068 
1069 #endif // NRF_802154_TEST_MODES_ENABLED
1070