From b14c5e4e8a1f1b403d680ed3c9037b4dee3390f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Mi=C5=9B?= Date: Tue, 8 Dec 2020 17:32:06 +0100 Subject: [PATCH] Release v1.9.0 Source commits: nrf-802.15.4-driver: 18ddc11a5e22b520f1f014f86d6ff24b3c9d89cb nrf-802.15.4-sl: 759a0a1854bd2e20e89769488edb8dbae292376a --- README.md | 18 +- .../include/fem/none/nrf_fem_config.h | 45 + .../include/fem/nrf_fem_abstract_interface.h | 86 + .../include/fem/nrf_fem_common_config.h | 73 + .../include/fem/nrf_fem_control_config.h | 65 + .../include}/fem/nrf_fem_protocol_api.h | 270 +- .../include/fem/simple_gpio/nrf_fem_config.h | 127 + .../fem/three_pin_gpio/nrf_fem_config.h | 136 + nrf_802154_sl/include/nrf_802154_sl_ant_div.h | 390 ++ nrf_802154_sl/include/nrf_802154_sl_coex.h | 176 + nrf_802154_sl/include/nrf_802154_sl_config.h | 78 + nrf_802154_sl/include/nrf_802154_sl_fault.h | 65 + nrf_802154_sl/include/nrf_802154_sl_log.h | 304 ++ nrf_802154_sl/include/nrf_802154_sl_periphs.h | 167 + nrf_802154_sl/include/nrf_802154_sl_rsch.h | 505 +++ nrf_802154_sl/include/nrf_802154_sl_stats.h | 44 + nrf_802154_sl/include/nrf_802154_sl_timer.h | 489 +++ nrf_802154_sl/include/nrf_802154_sl_utils.h | 117 + .../platform/clock/nrf_802154_clock.h | 60 +- .../platform/gpiote/nrf_802154_gpiote.h | 102 + .../platform/hp_timer/nrf_802154_hp_timer.h | 60 +- .../include}/platform/irq/nrf_802154_irq.h | 0 .../platform/lp_timer/nrf_802154_lp_timer.h | 60 +- .../include/rsch/coex/nrf_802154_wifi_coex.h | 155 + .../include}/rsch/nrf_802154_rsch.h | 136 +- .../include/rsch/nrf_802154_rsch_crit_sect.h | 99 + .../include/rsch/nrf_802154_rsch_prio_drop.h | 76 + .../include}/rsch/raal/nrf_raal_api.h | 61 +- .../include/rsch/raal/nrf_raal_config.h | 78 + .../include/timer}/nrf_802154_timer_coord.h | 60 +- .../include/timer}/nrf_802154_timer_sched.h | 60 +- .../open/src/nrf_802154_sl_ant_div.c | 159 + nrf_802154_sl/open/src/nrf_802154_sl_coex.c | 76 + nrf_802154_sl/open/src/nrf_802154_sl_fem.c | 141 + nrf_802154_sl/open/src/nrf_802154_sl_log.c | 54 + nrf_802154_sl/open/src/nrf_802154_sl_rsch.c | 187 + nrf_802154_sl/open/src/nrf_802154_sl_timer.c | 170 + .../platform/clock/nrf_802154_clock.c | 109 + .../platform/clock/nrf_802154_clock_mpsl.c | 114 + .../platform/clock/nrf_802154_clock_zephyr.c | 127 + .../gpiote/nrf_802154_gpiote_crit_sect.c | 88 + .../platform/gpiote/nrf_802154_gpiote_none.c | 106 + .../gpiote/nrf_802154_gpiote_zephyr.c | 108 + .../platform/hp_timer/nrf_802154_hp_timer.c | 77 +- .../platform/irq/nrf_802154_irq_baremetal.c | 14 +- .../platform/irq/nrf_802154_irq_zephyr.c | 4 +- .../platform/lp_timer/nrf_802154_lp_timer.c | 168 +- .../lp_timer/nrf_802154_lp_timer_none.c | 63 + src/fal/nrf_802154_fal.c | 37 +- src/fal/nrf_802154_fal.h | 37 +- src/fem/none/nrf_fem_config.h | 61 - src/fem/nrf_fem_control_config.h | 107 - src/fem/nrf_fem_protocol_legacy_api.h | 63 - src/fem/simple_gpio/nrf_fem_config.h | 127 - src/fem/simple_gpio/nrf_fem_simple_gpio.c | 470 --- src/fem/three_pin_gpio/nrf_fem_config.h | 149 - .../three_pin_gpio/nrf_fem_three_pin_gpio.c | 575 --- .../ack_generator/nrf_802154_ack_data.c | 79 +- .../ack_generator/nrf_802154_ack_data.h | 53 +- .../ack_generator/nrf_802154_ack_generator.c | 37 +- .../ack_generator/nrf_802154_ack_generator.h | 37 +- .../nrf_802154_enh_ack_generator.c | 49 +- .../nrf_802154_enh_ack_generator.h | 37 +- .../nrf_802154_imm_ack_generator.c | 39 +- .../nrf_802154_imm_ack_generator.h | 37 +- src/mac_features/nrf_802154_ack_timeout.c | 45 +- src/mac_features/nrf_802154_ack_timeout.h | 37 +- src/mac_features/nrf_802154_csma_ca.c | 197 +- src/mac_features/nrf_802154_csma_ca.h | 37 +- src/mac_features/nrf_802154_delayed_trx.c | 268 +- src/mac_features/nrf_802154_delayed_trx.h | 41 +- src/mac_features/nrf_802154_filter.c | 49 +- src/mac_features/nrf_802154_filter.h | 37 +- src/mac_features/nrf_802154_frame_parser.c | 37 +- src/mac_features/nrf_802154_frame_parser.h | 39 +- src/mac_features/nrf_802154_ifs.c | 246 ++ src/mac_features/nrf_802154_ifs.h | 72 + .../nrf_802154_precise_ack_timeout.c | 49 +- src/nrf_802154.c | 429 +- src/nrf_802154.h | 512 ++- src/nrf_802154_config.h | 231 +- src/nrf_802154_const.h | 48 +- src/nrf_802154_core.c | 3508 ++++++++--------- src/nrf_802154_core.h | 68 +- src/nrf_802154_core_hooks.c | 78 +- src/nrf_802154_core_hooks.h | 50 +- src/nrf_802154_critical_section.c | 60 +- src/nrf_802154_critical_section.h | 37 +- src/nrf_802154_debug.c | 174 +- src/nrf_802154_debug.h | 139 +- src/nrf_802154_debug_assert.c | 78 + src/nrf_802154_debug_core.h | 116 +- src/nrf_802154_debug_gpio.c | 103 + src/nrf_802154_debug_log.h | 71 + src/nrf_802154_debug_log_codes.h | 113 + src/nrf_802154_notification.h | 37 +- src/nrf_802154_notification_direct.c | 37 +- src/nrf_802154_notification_swi.c | 429 +- src/nrf_802154_nrfx_addons.h | 42 + src/nrf_802154_peripherals.h | 378 +- src/nrf_802154_peripherals_nrf52.h | 376 ++ src/nrf_802154_peripherals_nrf53.h | 165 + src/nrf_802154_pib.c | 301 +- src/nrf_802154_pib.h | 172 +- src/nrf_802154_priority_drop.h | 76 - src/nrf_802154_priority_drop_direct.c | 56 - src/nrf_802154_priority_drop_swi.c | 97 +- src/nrf_802154_procedures_duration.h | 42 +- src/nrf_802154_queue.c | 112 + src/nrf_802154_queue.h | 157 + src/nrf_802154_request.h | 53 +- src/nrf_802154_request_direct.c | 99 +- src/nrf_802154_request_swi.c | 607 ++- src/nrf_802154_rssi.c | 37 +- src/nrf_802154_rssi.h | 37 +- src/nrf_802154_rx_buffer.c | 37 +- src/nrf_802154_rx_buffer.h | 37 +- src/nrf_802154_stats.c | 116 + src/nrf_802154_stats.h | 107 + src/nrf_802154_swi.c | 856 +--- src/nrf_802154_swi.h | 239 +- src/nrf_802154_timer_coord.c | 268 -- src/nrf_802154_trx.c | 2466 ++++++++++++ src/nrf_802154_trx.h | 768 ++++ src/nrf_802154_trx_dppi.c | 234 ++ src/nrf_802154_trx_ppi.c | 271 ++ src/nrf_802154_trx_ppi_api.h | 158 + src/nrf_802154_types.h | 167 +- src/nrf_802154_utils.h | 93 +- src/platform/clock/nrf_802154_clock_nodrv.c | 132 - src/platform/clock/nrf_802154_clock_sdk.c | 114 - src/platform/clock/nrf_802154_clock_zephyr.c | 149 - src/platform/coex/nrf_802154_wifi_coex.h | 108 - src/platform/coex/nrf_802154_wifi_coex_none.c | 69 - .../lp_timer/nrf_802154_lp_timer_none.c | 62 - src/platform/random/nrf_802154_random.h | 37 +- .../random/nrf_802154_random_newlib.c | 50 +- .../random/nrf_802154_random_stdlib.c | 50 +- .../random/nrf_802154_random_zephyr.c | 4 +- .../temperature/nrf_802154_temperature.h | 37 +- .../temperature/nrf_802154_temperature_none.c | 37 +- src/rsch/nrf_802154_rsch.c | 561 --- src/rsch/nrf_802154_rsch_crit_sect.c | 154 - src/rsch/nrf_802154_rsch_crit_sect.h | 71 - src/rsch/raal/nrf_raal_config.h | 70 - src/rsch/raal/simulator/nrf_802154_debug.h | 74 - src/rsch/raal/simulator/nrf_raal_simulator.c | 251 -- src/rsch/raal/single_phy/single_phy.c | 89 - src/rsch/raal/softdevice/nrf_802154_debug.h | 74 - .../raal/softdevice/nrf_raal_softdevice.c | 830 ---- .../raal/softdevice/nrf_raal_softdevice.h | 141 - src/timer_scheduler/nrf_802154_timer_sched.c | 475 --- 152 files changed, 16695 insertions(+), 10961 deletions(-) create mode 100644 nrf_802154_sl/include/fem/none/nrf_fem_config.h create mode 100644 nrf_802154_sl/include/fem/nrf_fem_abstract_interface.h create mode 100644 nrf_802154_sl/include/fem/nrf_fem_common_config.h create mode 100644 nrf_802154_sl/include/fem/nrf_fem_control_config.h rename {src => nrf_802154_sl/include}/fem/nrf_fem_protocol_api.h (51%) create mode 100644 nrf_802154_sl/include/fem/simple_gpio/nrf_fem_config.h create mode 100644 nrf_802154_sl/include/fem/three_pin_gpio/nrf_fem_config.h create mode 100644 nrf_802154_sl/include/nrf_802154_sl_ant_div.h create mode 100644 nrf_802154_sl/include/nrf_802154_sl_coex.h create mode 100644 nrf_802154_sl/include/nrf_802154_sl_config.h create mode 100644 nrf_802154_sl/include/nrf_802154_sl_fault.h create mode 100644 nrf_802154_sl/include/nrf_802154_sl_log.h create mode 100644 nrf_802154_sl/include/nrf_802154_sl_periphs.h create mode 100644 nrf_802154_sl/include/nrf_802154_sl_rsch.h create mode 100644 nrf_802154_sl/include/nrf_802154_sl_stats.h create mode 100644 nrf_802154_sl/include/nrf_802154_sl_timer.h create mode 100644 nrf_802154_sl/include/nrf_802154_sl_utils.h rename {src => nrf_802154_sl/include}/platform/clock/nrf_802154_clock.h (57%) create mode 100644 nrf_802154_sl/include/platform/gpiote/nrf_802154_gpiote.h rename {src => nrf_802154_sl/include}/platform/hp_timer/nrf_802154_hp_timer.h (61%) rename {src => nrf_802154_sl/include}/platform/irq/nrf_802154_irq.h (100%) rename {src => nrf_802154_sl/include}/platform/lp_timer/nrf_802154_lp_timer.h (75%) create mode 100644 nrf_802154_sl/include/rsch/coex/nrf_802154_wifi_coex.h rename {src => nrf_802154_sl/include}/rsch/nrf_802154_rsch.h (58%) create mode 100644 nrf_802154_sl/include/rsch/nrf_802154_rsch_crit_sect.h create mode 100644 nrf_802154_sl/include/rsch/nrf_802154_rsch_prio_drop.h rename {src => nrf_802154_sl/include}/rsch/raal/nrf_raal_api.h (67%) create mode 100644 nrf_802154_sl/include/rsch/raal/nrf_raal_config.h rename {src => nrf_802154_sl/include/timer}/nrf_802154_timer_coord.h (54%) rename {src/timer_scheduler => nrf_802154_sl/include/timer}/nrf_802154_timer_sched.h (72%) create mode 100644 nrf_802154_sl/open/src/nrf_802154_sl_ant_div.c create mode 100644 nrf_802154_sl/open/src/nrf_802154_sl_coex.c create mode 100644 nrf_802154_sl/open/src/nrf_802154_sl_fem.c create mode 100644 nrf_802154_sl/open/src/nrf_802154_sl_log.c create mode 100644 nrf_802154_sl/open/src/nrf_802154_sl_rsch.c create mode 100644 nrf_802154_sl/open/src/nrf_802154_sl_timer.c create mode 100644 nrf_802154_sl/platform/clock/nrf_802154_clock.c create mode 100644 nrf_802154_sl/platform/clock/nrf_802154_clock_mpsl.c create mode 100644 nrf_802154_sl/platform/clock/nrf_802154_clock_zephyr.c create mode 100644 nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_crit_sect.c create mode 100644 nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_none.c create mode 100644 nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_zephyr.c rename {src => nrf_802154_sl}/platform/hp_timer/nrf_802154_hp_timer.c (51%) rename {src => nrf_802154_sl}/platform/irq/nrf_802154_irq_baremetal.c (91%) rename {src => nrf_802154_sl}/platform/irq/nrf_802154_irq_zephyr.c (95%) rename {src => nrf_802154_sl}/platform/lp_timer/nrf_802154_lp_timer.c (80%) create mode 100644 nrf_802154_sl/platform/lp_timer/nrf_802154_lp_timer_none.c delete mode 100644 src/fem/none/nrf_fem_config.h delete mode 100644 src/fem/nrf_fem_control_config.h delete mode 100644 src/fem/nrf_fem_protocol_legacy_api.h delete mode 100644 src/fem/simple_gpio/nrf_fem_config.h delete mode 100644 src/fem/simple_gpio/nrf_fem_simple_gpio.c delete mode 100644 src/fem/three_pin_gpio/nrf_fem_config.h delete mode 100644 src/fem/three_pin_gpio/nrf_fem_three_pin_gpio.c create mode 100644 src/mac_features/nrf_802154_ifs.c create mode 100644 src/mac_features/nrf_802154_ifs.h create mode 100644 src/nrf_802154_debug_assert.c create mode 100644 src/nrf_802154_debug_gpio.c create mode 100644 src/nrf_802154_debug_log.h create mode 100644 src/nrf_802154_debug_log_codes.h create mode 100644 src/nrf_802154_nrfx_addons.h create mode 100644 src/nrf_802154_peripherals_nrf52.h create mode 100644 src/nrf_802154_peripherals_nrf53.h delete mode 100644 src/nrf_802154_priority_drop.h delete mode 100644 src/nrf_802154_priority_drop_direct.c create mode 100644 src/nrf_802154_queue.c create mode 100644 src/nrf_802154_queue.h create mode 100644 src/nrf_802154_stats.c create mode 100644 src/nrf_802154_stats.h delete mode 100644 src/nrf_802154_timer_coord.c create mode 100644 src/nrf_802154_trx.c create mode 100644 src/nrf_802154_trx.h create mode 100644 src/nrf_802154_trx_dppi.c create mode 100644 src/nrf_802154_trx_ppi.c create mode 100644 src/nrf_802154_trx_ppi_api.h delete mode 100644 src/platform/clock/nrf_802154_clock_nodrv.c delete mode 100644 src/platform/clock/nrf_802154_clock_sdk.c delete mode 100644 src/platform/clock/nrf_802154_clock_zephyr.c delete mode 100644 src/platform/coex/nrf_802154_wifi_coex.h delete mode 100644 src/platform/coex/nrf_802154_wifi_coex_none.c delete mode 100644 src/platform/lp_timer/nrf_802154_lp_timer_none.c delete mode 100644 src/rsch/nrf_802154_rsch.c delete mode 100644 src/rsch/nrf_802154_rsch_crit_sect.c delete mode 100644 src/rsch/nrf_802154_rsch_crit_sect.h delete mode 100644 src/rsch/raal/nrf_raal_config.h delete mode 100644 src/rsch/raal/simulator/nrf_802154_debug.h delete mode 100644 src/rsch/raal/simulator/nrf_raal_simulator.c delete mode 100644 src/rsch/raal/single_phy/single_phy.c delete mode 100644 src/rsch/raal/softdevice/nrf_802154_debug.h delete mode 100644 src/rsch/raal/softdevice/nrf_raal_softdevice.c delete mode 100644 src/rsch/raal/softdevice/nrf_raal_softdevice.h delete mode 100644 src/timer_scheduler/nrf_802154_timer_sched.c diff --git a/README.md b/README.md index be4432e..739582a 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,15 @@ # nRF IEEE 802.15.4 radio driver -[![Build Status][travis-svg]][travis] - -[travis]: https://travis-ci.org/NordicSemiconductor/nRF-IEEE-802.15.4-radio-driver -[travis-svg]: https://travis-ci.org/NordicSemiconductor/nRF-IEEE-802.15.4-radio-driver.svg?branch=master - -The nRF IEEE 802.15.4 radio driver implements the IEEE 802.15.4 PHY layer on the Nordic Semiconductor nRF52811 and nRF52840 SoCs. +The nRF IEEE 802.15.4 radio driver implements the IEEE 802.15.4 PHY layer on the following Nordic Semiconductor SoCs: + - nRF52811 + - nRF52833 + - nRF52840 + - nRF5340 The architecture of the nRF IEEE 802.15.4 radio driver is independent of the OS and IEEE 802.15.4 MAC layer. It allows to use the driver in any IEEE 802.15.4 based stacks that implement protocols such as Thread, ZigBee, or RF4CE. -In addition, it was designed to work with multiprotocol applications. The driver allows to share the RADIO peripheral with other PHY protocol drivers, for example, Bluetooth LE. - -For more information and a detailed description of the driver, see the [Wiki](https://github.com/NordicSemiconductor/nRF-IEEE-802.15.4-radio-driver/wiki). +In addition, it was designed to work with multiprotocol applications. +The driver allows to share the RADIO peripheral with other PHY protocol drivers, for example, Bluetooth LE. -Note that the *nRF-IEEE-802.15.4-radio-driver.packsc* file is a project building description used for internal testing in Nordic Semiconductor. This file is NOT needed to build the driver with any other tool. +For more information and a detailed description of the driver, see the [Wiki](https://infocenter.nordicsemi.com/topic/struct_drivers/struct/radio_driver_latest.html). diff --git a/nrf_802154_sl/include/fem/none/nrf_fem_config.h b/nrf_802154_sl/include/fem/none/nrf_fem_config.h new file mode 100644 index 0000000..c495a06 --- /dev/null +++ b/nrf_802154_sl/include/fem/none/nrf_fem_config.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_FEM_NONE_CONFIG_H_ +#define NRF_FEM_NONE_CONFIG_H_ + +/** @brief The ID of "none" FEM type (e.g. for run-time selection) */ +#define NRF_FEM_IF_TYPE_NONE 0 + +#endif /* NRF_FEM_NONE_CONFIG_H_ */ diff --git a/nrf_802154_sl/include/fem/nrf_fem_abstract_interface.h b/nrf_802154_sl/include/fem/nrf_fem_abstract_interface.h new file mode 100644 index 0000000..97adc60 --- /dev/null +++ b/nrf_802154_sl/include/fem/nrf_fem_abstract_interface.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_FEM_ABSTRACT_INTERFACE_H_ +#define NRF_FEM_ABSTRACT_INTERFACE_H_ + +#include +#include + +#include "nrf_fem_protocol_api.h" + +/** + * @brief Set of pointers to functions that enables run-time choice of FEM implementation. + */ +typedef struct +{ + uint32_t fem_type_id; + + int32_t (* p_pa_configuration_set)(const nrf_802154_fal_event_t * const p_activate_event, + const nrf_802154_fal_event_t * const p_deactivate_event); + int32_t (* p_lna_configuration_set)(const nrf_802154_fal_event_t * const p_activate_event, + const nrf_802154_fal_event_t * const p_deactivate_event); + int32_t (* p_pa_configuration_clear)(void); + int32_t (* p_lna_configuration_clear)(void); + void (* p_deactivate_now)(nrf_fal_functionality_t type); + void (* p_cleanup)(void); + bool (* p_prepare_powerdown)(NRF_TIMER_Type * p_instance, + uint32_t compare_channel, + nrf_ppi_channel_t ppi_id); + void (* p_pa_is_configured)(int8_t * const p_gain); + int32_t (* p_abort_set)(uint32_t event, nrf_ppi_channel_group_t group); + int32_t (* p_abort_extend)(nrf_ppi_channel_t channel_to_add, nrf_ppi_channel_group_t group); + int32_t (* p_abort_reduce)(nrf_ppi_channel_t channel_to_remove, nrf_ppi_channel_group_t group); + int32_t (* p_abort_clear)(void); +} nrf_802154_fal_interface_t; + +/** + * @brief Connects to one of FEM implementation + * + * @param[in] p_methods Pointer to structure of pointers. This will be used in case of future calls + * to specific FEM implementation methods. + * + * @note This must be used by FEM implementation "constructor" and this is the only case + * in which it can be used. + * + * @retval ::NRFX_SUCCESS The "link" was successfuly created. + * @retval ::NRFX_ERROR_FORBIDDEN Some error occured (e.q. null pointer was passed) + */ +int32_t nrf_802154_fal_interface_set(const nrf_802154_fal_interface_t * p_methods); + +#endif // NRF_FEM_ABSTRACT_INTERFACE_ diff --git a/nrf_802154_sl/include/fem/nrf_fem_common_config.h b/nrf_802154_sl/include/fem/nrf_fem_common_config.h new file mode 100644 index 0000000..fd4bb02 --- /dev/null +++ b/nrf_802154_sl/include/fem/nrf_fem_common_config.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_FEM_COMMON_CONFIG_H_ +#define NRF_FEM_COMMON_CONFIG_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configuration parameters for pins that enable or disable (or both) either Power Amplifier (PA) or Low Noise Amplifier (LNA). + */ +typedef struct +{ + bool enable; /* Enable toggling for this pin. */ + bool active_high; /* If true, the pin will be active high. Otherwise, the pin will be active low. */ + uint8_t gpio_pin; /* GPIO pin number for the pin. */ + uint8_t gpiote_ch_id; /* GPIOTE channel to be used for toggling pins. */ +} nrf_fem_gpiote_pin_config_t; + +/** Mask of GPIO pins used for FEM control. */ +#define NRF_802154_FEM_PINS_USED_MASK 0 + +/** Mask of PPI channels used for FEM control. */ +#define NRF_802154_FEM_PPI_CHANNELS_USED_MASK 0 + +/** Mask of GPIOTE channels used for FEM control. */ +#define NRF_802154_FEM_GPIOTE_CHANNELS_USED_MASK 0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/nrf_802154_sl/include/fem/nrf_fem_control_config.h b/nrf_802154_sl/include/fem/nrf_fem_control_config.h new file mode 100644 index 0000000..89f1b71 --- /dev/null +++ b/nrf_802154_sl/include/fem/nrf_fem_control_config.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_FEM_CONTROL_CONFIG_H_ +#define NRF_FEM_CONTROL_CONFIG_H_ + +#include "none/nrf_fem_config.h" +#include "simple_gpio/nrf_fem_config.h" +#include "three_pin_gpio/nrf_fem_config.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @section Configuration + */ + +/** + * @brief Retrieves last selected PA, LNA device interface ID code. + */ +int32_t nrf_fem_interface_type_get(void); + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_FEM_CONTROL_CONFIG_H_ */ diff --git a/src/fem/nrf_fem_protocol_api.h b/nrf_802154_sl/include/fem/nrf_fem_protocol_api.h similarity index 51% rename from src/fem/nrf_fem_protocol_api.h rename to nrf_802154_sl/include/fem/nrf_fem_protocol_api.h index 3c83547..28fe06c 100644 --- a/src/fem/nrf_fem_protocol_api.h +++ b/nrf_802154_sl/include/fem/nrf_fem_protocol_api.h @@ -1,31 +1,39 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2020, Nordic Semiconductor ASA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -40,18 +48,20 @@ * When the PA/LNA module is configured, the stack can call the provided enable functions before radio activity * to enable the PA or LNA timer configurations for the upcoming radio activity. * By default, PA/LNA is automatically deactivated on the radio DISABLED event. - * This can be disabled, so that a manual deactivation can be performed instead. */ #ifndef NRF_FEM_PROTOCOL_API_H__ #define NRF_FEM_PROTOCOL_API_H__ -#include "nrf_fem_control_config.h" -#include "nrf_fem_protocol_legacy_api.h" +#include -#include "nrf_error.h" -#include "nrf_ppi.h" -#include "nrf_timer.h" +#if defined(NRF52_SERIES) +#include "hal/nrf_ppi.h" +#elif defined(NRF53_SERIES) +#include "hal/nrf_dppi.h" +#else +#error Unsupported chip +#endif typedef enum { @@ -82,32 +92,34 @@ typedef struct { struct { - NRF_TIMER_Type * p_timer_instance; /* Pointer to a 1-us resolution timer instance. */ - uint32_t counter_value; /* Timer value when the radio activity starts. */ - uint8_t compare_channel_mask; /* Mask of the compare channels that can be used by the FEM to schedule its own tasks. */ + NRF_TIMER_Type * p_timer_instance; /* Pointer to a 1-us resolution timer instance. */ + + struct + { + uint32_t start; /* Timer value when the FEM can start preparing PA/LNA. */ + uint32_t end; /* Timer value at which the PA/LNA have to be prepared. Radio operation shall start at this point. */ + } counter_period; + uint8_t compare_channel_mask; /* Mask of the compare channels that can be used by the FEM to schedule its own tasks. */ } timer; struct { - uint32_t register_address; /* Address of event register. */ + uint32_t register_address; /* Address of event register. */ } generic; - struct - { - uint8_t ch_id; /* Number of the PPI which was provided. */ - } ppi; } event; bool override_ppi; /* False to ignore the PPI channel below and use the one set by application. True to use the PPI channel below. */ uint8_t ppi_ch_id; /* PPI channel to be used for this event. */ nrf_802154_fal_event_type_t type; /* Type of event source. */ } nrf_802154_fal_event_t; -#if ENABLE_FEM - /** * @brief Sets up PA using the provided events for the upcoming radio transmission. * * Multiple configurations can be provided by repeating calls to this function (that is, you can set the activate and the deactivate events in multiple calls, * and the configuration is preserved between calls). * + * The order of calls of this function and its `lna` counterpart must match the order of radio operations. + * I.e. if you want to perform the CCA and then send the frame, you need first to issue @ref nrf_802154_fal_lna_configuration_set and only after @ref nrf_802154_fal_pa_configuration_set. + * * If a NRF_802154_PA_LNA_EVENT_TYPE_TIMER timer event is provided, the PA will be configured to activate or deactivate at the application-configured time gap * before the timer instance reaches the given register_value. The time gap is set via @ref nrf_fem_interface_configuration_set. * @@ -121,13 +133,13 @@ typedef struct * * @pre To activate PA, nrf_fem_interface_configuration_set() must have been called first. * - * @note If a timer event is provided, the caller of this function is responsible for starting the timer and its shorts. - * Moreover, the caller is responsible for stopping the timer no earlier than the provided compare channel expires. + * @note If a timer event is provided, the caller of this function is responsible for starting the timer and configuring its shorts. + * Moreover, the caller is responsible for stopping the timer no earlier than the compare channel of the lowest ID among the provided ones does expire. * - * @retval ::NRF_SUCCESS PA activate setup is successful. - * @retval ::NRF_ERROR_FORBIDDEN PA is currently disabled. - * @retval ::NRF_ERROR_INVALID_STATE PA activate setup could not be performed due to invalid or missing configuration parameters - * in p_activate_event or p_deactivate_event, or both. + * @retval ::NRFX_SUCCESS PA activate setup is successful. + * @retval ::NRFX_ERROR_FORBIDDEN PA is currently disabled. + * @retval ::NRFX_ERROR_INVALID_STATE PA activate setup could not be performed due to invalid or missing configuration parameters + * in p_activate_event or p_deactivate_event, or both. */ int32_t nrf_802154_fal_pa_configuration_set(const nrf_802154_fal_event_t * const p_activate_event, const nrf_802154_fal_event_t * const p_deactivate_event); @@ -135,16 +147,12 @@ int32_t nrf_802154_fal_pa_configuration_set(const nrf_802154_fal_event_t * const /** * @brief Clears up the configuration provided by the @ref nrf_802154_fal_pa_configuration_set function. * - * @param[in] p_activate_event Pointer to the activation event structure. - * @param[in] p_deactivate_event Pointer to the deactivation event structure. - * - * @retval ::NRF_SUCCESS PA activate setup purge is successful. - * @retval ::NRF_ERROR_FORBIDDEN PA is currently disabled. - * @retval ::NRF_ERROR_INVALID_STATE PA activate setup purge could not be performed due to invalid or missing configuration parameters - * in p_activate_event or p_deactivate_event, or both. + * @retval ::NRFX_SUCCESS PA activate setup purge is successful. + * @retval ::NRFX_ERROR_FORBIDDEN PA is currently disabled. + * @retval ::NRFX_ERROR_INVALID_STATE PA activate setup purge could not be performed due to invalid or missing configuration parameters, + * that were previously used in @ref nrf_802154_fal_pa_configuration_set call. */ -int32_t nrf_802154_fal_pa_configuration_clear(const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event); +int32_t nrf_802154_fal_pa_configuration_clear(void); /** * @brief Sets up LNA using the provided event for the upcoming radio reception. @@ -152,6 +160,9 @@ int32_t nrf_802154_fal_pa_configuration_clear(const nrf_802154_fal_event_t * con * Multiple configurations can be provided by repeating calls to this function (that is, you can set the activate and the deactivate event in multiple calls, * and the configuration is preserved between calls). * + * The order of calls of this function and its `pa` counterpart must match the order of radio operations. + * I.e. if you want to perform the CCA and then send the frame, you need first to issue @ref nrf_802154_fal_lna_configuration_set and only after @ref nrf_802154_fal_pa_configuration_set. + * * If a NRF_802154_PA_LNA_EVENT_TYPE_TIMER timer event is provided, the LNA will be configured to activate or deactivate at the application-configured time gap * before the timer instance reaches the given register_value. The time gap is set via @ref nrf_fem_interface_configuration_set. * @@ -165,13 +176,13 @@ int32_t nrf_802154_fal_pa_configuration_clear(const nrf_802154_fal_event_t * con * * @pre To activate LNA, nrf_fem_interface_configuration_set() must have been called first. * - * @note If a timer event is provided, the caller of this function is responsible for starting the timer and its shorts. - * Moreover, the caller is responsible for stopping the timer no earlier than the provided compare channel expires. + * @note If a timer event is provided, the caller of this function is responsible for starting the timer and configuring its shorts. + * Moreover, the caller is responsible for stopping the timer no earlier than the compare channel of the lowest ID among the provided ones does expire. * - * @retval ::NRF_SUCCESS LNA activate setup is successful. - * @retval ::NRF_ERROR_FORBIDDEN LNA is currently disabled. - * @retval ::NRF_ERROR_INVALID_STATE LNA activate setup could not be performed due to invalid or missing configuration parameters - * in p_activate_event or p_deactivate_event, or both. + * @retval ::NRFX_SUCCESS LNA activate setup is successful. + * @retval ::NRFX_ERROR_FORBIDDEN LNA is currently disabled. + * @retval ::NRFX_ERROR_INVALID_STATE LNA activate setup could not be performed due to invalid or missing configuration parameters + * in p_activate_event or p_deactivate_event, or both. */ int32_t nrf_802154_fal_lna_configuration_set(const nrf_802154_fal_event_t * const p_activate_event, const nrf_802154_fal_event_t * const p_deactivate_event); @@ -179,23 +190,62 @@ int32_t nrf_802154_fal_lna_configuration_set(const nrf_802154_fal_event_t * cons /** * @brief Clears up the configuration provided by the @ref nrf_802154_fal_lna_configuration_set function. * - * @param[in] p_activate_event Pointer to the activation event structure. - * @param[in] p_deactivate_event Pointer to the deactivation event structure. * - * @retval ::NRF_SUCCESS LNA activate setup purge is successful. - * @retval ::NRF_ERROR_FORBIDDEN LNA is currently disabled. - * @retval ::NRF_ERROR_INVALID_STATE LNA activate setup purge could not be performed due to invalid or missing configuration parameters - * in p_activate_event or p_deactivate_event, or both. + * @retval ::NRFX_SUCCESS LNA activate setup purge is successful. + * @retval ::NRFX_ERROR_FORBIDDEN LNA is currently disabled. + * @retval ::NRFX_ERROR_INVALID_STATE LNA activate setup purge could not be performed due to invalid or missing configuration parameters, + * that were previously used in @ref nrf_802154_fal_lna_configuration_set call. */ -int32_t nrf_802154_fal_lna_configuration_clear( - const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event); +int32_t nrf_802154_fal_lna_configuration_clear(void); /** * @brief Deactivates PA/LNA pins with immediate effect. */ void nrf_802154_fal_deactivate_now(nrf_fal_functionality_t type); +#if defined(NRF52_SERIES) +/** + * @brief Instruct FEM to disable PA and LNA as soon as possible using the group following the event. + * + * @param[in] event Address of the event which is triggered when the abort condition occurs. + * @param[in] group PPI Group which shall be disabled when the abort event is triggered. + * + * @retval ::NRFX_SUCCESS Setting of the abort sequence path is successful. + * @retval ::NRFX_ERROR_FORBIDDEN Setting of the abort sequence path could not be performed. + */ +int32_t nrf_802154_fal_abort_set(uint32_t event, nrf_ppi_channel_group_t group); + +/** + * @brief Adds one more PPI channel to the PPI Group prepared by the @ref nrf_802154_fal_abort_set function. + * + * @param[in] channel_to_add + * @param[in] group + * + * @retval ::NRFX_SUCCESS Setting of the abort sequence path is successful. + */ +int32_t nrf_802154_fal_abort_extend(nrf_ppi_channel_t channel_to_add, + nrf_ppi_channel_group_t group); + +/** + * @brief Removes one PPI channel from the PPI Group prepared by the @ref nrf_802154_fal_abort_set function. + * + * @param[in] channel_to_remove + * @param[in] group + * + * @retval ::NRFX_SUCCESS Setting of the abort sequence path is successful. + */ +int32_t nrf_802154_fal_abort_reduce(nrf_ppi_channel_t channel_to_remove, + nrf_ppi_channel_group_t group); + +/** + * @brief Clears up the configuration provided by the @ref nrf_802154_fal_abort_set function. + * + * @retval ::NRFX_SUCCESS Clearing of the abort sequence path is successful. + * @retval ::NRFX_ERROR_FORBIDDEN Clearing was not done - the possible reason is that there was nothing to clear. + */ +int32_t nrf_802154_fal_abort_clear(void); +#endif // NRF52_SERIES + /** * @brief Cleans up the configured PA/LNA timer/radio instance and resources of PPI and GPIOTE. * The function resets the hardware that has been set up for the PA/LNA activation. The PA and LNA module control configuration parameters are not deleted. @@ -212,6 +262,7 @@ void nrf_802154_fal_cleanup(void); */ void nrf_802154_fal_pa_is_configured(int8_t * const p_gain); +#if defined(NRF52_SERIES) /** * @brief Prepares the FEM module to switch to the Power Down state. * @@ -225,79 +276,6 @@ void nrf_802154_fal_pa_is_configured(int8_t * const p_gain); bool nrf_fem_prepare_powerdown(NRF_TIMER_Type * p_instance, uint32_t compare_channel, nrf_ppi_channel_t ppi_id); - -#else // ENABLE_FEM - -static inline int32_t nrf_802154_fal_pa_configuration_set( - const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - (void)p_activate_event; - (void)p_deactivate_event; - return NRF_ERROR_FORBIDDEN; -} - -static inline int32_t nrf_802154_fal_pa_configuration_clear( - const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - (void)p_activate_event; - (void)p_deactivate_event; - return NRF_ERROR_FORBIDDEN; -} - -static inline int32_t nrf_802154_fal_lna_configuration_set( - const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - (void)p_activate_event; - (void)p_deactivate_event; - return NRF_ERROR_FORBIDDEN; -} - -static inline int32_t nrf_802154_fal_lna_configuration_clear( - const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - (void)p_activate_event; - (void)p_deactivate_event; - return NRF_ERROR_FORBIDDEN; -} - -static inline void nrf_802154_fal_deactivate_now(nrf_fal_functionality_t type) -{ - (void)type; -} - -static inline void nrf_802154_fal_cleanup(void) -{ - -} - -static inline bool nrf_fem_prepare_powerdown(NRF_TIMER_Type * p_instance, - uint32_t compare_channel, - nrf_ppi_channel_t ppi_id) -{ - (void)p_instance; - (void)compare_channel; - (void)ppi_id; - return false; -} - -static inline void nrf_802154_fal_pa_is_configured(int8_t * const p_gain) -{ - *p_gain = 0; -} - -#define NRF_802154_FEM_PINS_USED_MASK 0 -#define NRF_802154_FEM_PPI_CHANNELS_USED_MASK 0 -#define NRF_802154_FEM_GPIOTE_CHANNELS_USED_MASK 0 - -#endif // ENABLE_FEM +#endif // NRF52_SERIES #endif // NRF_FEM_PROTOCOL_API_H__ - -/** - @} - @} - */ diff --git a/nrf_802154_sl/include/fem/simple_gpio/nrf_fem_config.h b/nrf_802154_sl/include/fem/simple_gpio/nrf_fem_config.h new file mode 100644 index 0000000..9b905a1 --- /dev/null +++ b/nrf_802154_sl/include/fem/simple_gpio/nrf_fem_config.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_FEM_SIMPLE_GPIO_CONFIG_H_ +#define NRF_FEM_SIMPLE_GPIO_CONFIG_H_ + +#include +#include +#include "../nrf_fem_common_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief The ID of "simpe gpio" FEM type (e.g. for run-time selection) */ +#define NRF_FEM_IF_TYPE_SIMPLE_GPIO 1 + +/** + * @brief Configuration parameters for the PA/LNA interface in the "simple gpio" variant + */ +typedef struct +{ + struct + { + uint32_t pa_time_gap_us; /* Time between the activation of the PA pin and the start of the radio transmission. */ + uint32_t lna_time_gap_us; /* Time between the activation of the LNA pin and the start of the radio reception. */ + int8_t pa_gain_db; /* Configurable PA gain. Ignored if the amplifier is not supporting this feature. */ + int8_t lna_gain_db; /* Configurable LNA gain. Ignored if the amplifier is not supporting this feature. */ + } fem_config; + + nrf_fem_gpiote_pin_config_t pa_pin_config; /* Power Amplifier pin configuration. */ + nrf_fem_gpiote_pin_config_t lna_pin_config; /* Low Noise Amplifier pin configuration. */ + + uint8_t ppi_channels[2]; + +} nrf_fem_simple_gpio_interface_config_t; + +/** + * @brief Configures the PA and LNA device interface. + * + * This function sets device interface parameters for the PA/LNA module. + * The module can then be used to control a power amplifier or a low noise amplifier (or both) through the given interface and resources. + * + * The function also sets the PPI and GPIOTE channels to be configured for the PA/LNA interface. + * + * @param[in] p_config Pointer to the interface parameters for the PA/LNA device. + * + * @retval ::NRFX_SUCCESS PA/LNA control successfully configured. + * @retval ::NRFX_ERROR_NOT_SUPPORTED PA/LNA is not available. + * + */ +int32_t nrf_fem_simple_gpio_interface_config_set( + nrf_fem_simple_gpio_interface_config_t const * const p_config); + +/** + * @brief Retrieves the configuration of PA and LNA device interface. + * + * This function gets device interface parameters for the PA/LNA module. + * The module can then be used to control a power amplifier or a low noise amplifier (or both) through the given interface and resources. + * + * + * @param[in] p_config Pointer to the interface parameters for the PA/LNA device to be populated. + * + * @retval ::NRFX_SUCCESS PA/LNA control successfully configured. + * @retval ::NRFX_ERROR_NOT_SUPPORTED PA/LNA is not available. + * @retval ::NRFX_ERROR_FORBIDDEN The "simpe gpio" is not currently selected as the FEM type. + * + */ +int32_t nrf_fem_simple_gpio_interface_config_get(nrf_fem_simple_gpio_interface_config_t * p_config); + +/** + * @section Timings. + */ + +/** Time in microseconds when PA GPIO is activated before the radio is ready for transmission. */ +#define NRF_FEM_SIMPLE_GPIO_PA_TIME_IN_ADVANCE_US 23 + +/** Time in microseconds when LNA GPIO is activated before the radio is ready for reception. */ +#define NRF_FEM_SIMPLE_GPIO_LNA_TIME_IN_ADVANCE_US 5 + +/** + * @section Gains. + */ + +#define NRF_FEM_SIMPLE_GPIO_PA_GAIN_DB 20 +#define NRF_FEM_SIMPLE_GPIO_LNA_GAIN_DB 20 + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_FEM_SIMPLE_GPIO_CONFIG_H_ */ diff --git a/nrf_802154_sl/include/fem/three_pin_gpio/nrf_fem_config.h b/nrf_802154_sl/include/fem/three_pin_gpio/nrf_fem_config.h new file mode 100644 index 0000000..5bd95e9 --- /dev/null +++ b/nrf_802154_sl/include/fem/three_pin_gpio/nrf_fem_config.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_FEM_3PIN_GPIO_CONFIG_H_ +#define NRF_FEM_3PIN_GPIO_CONFIG_H_ + +#include +#include +#include "../nrf_fem_common_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief The ID of "3pin gpio" FEM type (e.g. for run-time selection) */ +#define NRF_FEM_IF_TYPE_THREE_PIN_GPIO 2 + +/** + * @brief Configuration parameters for the PA/LNA interface in the "3-pin gpio" variant + */ +typedef struct +{ + struct + { + uint32_t pa_time_gap_us; /* Time between the activation of the PA pin and the start of the radio transmission. */ + uint32_t lna_time_gap_us; /* Time between the activation of the LNA pin and the start of the radio reception. */ + uint32_t pdn_settle_us; /* The time between activating the PDN and asserting the PA/LNA pin. */ + uint32_t trx_hold_us; /* The time between deasserting the PA/LNA pin and deactivating PDN. */ + int8_t pa_gain_db; /* Configurable PA gain. Ignored if the amplifier is not supporting this feature. */ + int8_t lna_gain_db; /* Configurable LNA gain. Ignored if the amplifier is not supporting this feature. */ + } fem_config; + + nrf_fem_gpiote_pin_config_t pa_pin_config; /* Power Amplifier pin configuration. */ + nrf_fem_gpiote_pin_config_t lna_pin_config; /* Low Noise Amplifier pin configuration. */ + nrf_fem_gpiote_pin_config_t pdn_pin_config; /* Power Down pin configuration. */ + + uint8_t ppi_channels[3]; + +} nrf_fem_3pin_gpio_interface_config_t; + +/** + * @brief Configures the PA and LNA device interface. + * + * This function sets device interface parameters for the PA/LNA module. + * The module can then be used to control a power amplifier or a low noise amplifier (or both) through the given interface and resources. + * + * The function also sets the PPI and GPIOTE channels to be configured for the PA/LNA interface. + * + * @param[in] p_config Pointer to the interface parameters for the PA/LNA device. + * + * @retval ::NRFX_SUCCESS PA/LNA control successfully configured. + * @retval ::NRFX_ERROR_NOT_SUPPORTED PA/LNA is not available. + * + */ +int32_t nrf_fem_3pin_gpio_interface_config_set( + nrf_fem_3pin_gpio_interface_config_t const * const p_config); + +/** + * @brief Retrieves the configuration of PA and LNA device interface. + * + * This function gets device interface parameters for the PA/LNA module. + * The module can then be used to control a power amplifier or a low noise amplifier (or both) through the given interface and resources. + * + * + * @param[in] p_config Pointer to the interface parameters for the PA/LNA device to be populated. + * + * @retval ::NRFX_SUCCESS PA/LNA control successfully configured. + * @retval ::NRFX_ERROR_NOT_SUPPORTED PA/LNA is not available. + * @retval ::NRFX_ERROR_FORBIDDEN The "3pin gpio" is not currently selected as the FEM type. + * + */ +int32_t nrf_fem_3pin_gpio_interface_config_get(nrf_fem_3pin_gpio_interface_config_t * p_config); + +/** + * @section Timings. + */ + +/** Time in microseconds when PA GPIO is activated before the radio is ready for transmission. */ +#define NRF_FEM_THREE_PIN_GPIO_PA_TIME_IN_ADVANCE_US 13 + +/** Time in microseconds when LNA GPIO is activated before the radio is ready for reception. */ +#define NRF_FEM_THREE_PIN_GPIO_LNA_TIME_IN_ADVANCE_US 13 + +/** The time between activating the PDN and asserting the RX_EN/TX_EN. */ +#define NRF_FEM_THREE_PIN_GPIO_PDN_SETTLE_US 18 + +/** The time between deasserting the RX_EN/TX_EN and deactivating PDN. */ +#define NRF_FEM_THREE_PIN_GPIO_TRX_HOLD_US 5 + +/** + * @section Gains. + */ + +#define NRF_FEM_THREE_PIN_GPIO_PA_GAIN_DB 20 +#define NRF_FEM_THREE_PIN_GPIO_LNA_GAIN_DB 20 + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_FEM_3PIN_GPIO_CONFIG_H_ */ diff --git a/nrf_802154_sl/include/nrf_802154_sl_ant_div.h b/nrf_802154_sl/include/nrf_802154_sl_ant_div.h new file mode 100644 index 0000000..2afdac9 --- /dev/null +++ b/nrf_802154_sl/include/nrf_802154_sl_ant_div.h @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief 802.15.4 antenna diversity module. + */ + +#ifndef NRF_802154_SL_ANT_DIV_H +#define NRF_802154_SL_ANT_DIV_H + +#include +#include + +#include "nrf.h" + +/** + * @brief RSSI measurement results. + */ +#define NRF_802154_SL_ANT_DIV_RSSI_INVALID INT8_MAX + +/** + * @brief Priority of TIMER IRQ. + */ +#define NRF_802154_SL_ANT_DIV_IRQ_PRIORITY 1 + +/** + * @brief Recommended value of time in microseconds between consecutive antenna switches. + * + * When antenna diversity interface operates in @ref NRF_802154_SL_ANT_DIV_MODE_AUTO mode, + * the antenna is toggled periodically in order to maximize the chance of receiving a frame + * preamble. The time between consecutive antenna toggles is configured through + * @ref nrf_802154_sl_ant_div_cfg_set function. The value specified by this macro is the + * recommended value of @p toggle_time parameter that should be set if no particular reasons + * for a different configuration exist. + */ +#define NRF_802154_SL_ANT_DIV_DEFAULT_TOGGLE_TIME_US 40 + +/** + * @brief Mode of the antenna diversity module. + * + * Possible values: + * - @ref NRF_802154_SL_ANT_DIV_MODE_DISABLED, + * - @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL, + * - @ref NRF_802154_SL_ANT_DIV_MODE_AUTO + */ +typedef uint8_t nrf_802154_sl_ant_div_mode_t; + +#define NRF_802154_SL_ANT_DIV_MODE_DISABLED 0x00 // !< Antenna diversity is disabled - Antenna will not be controlled by sl_ant_div module. While in this mode, current antenna is unspecified. +#define NRF_802154_SL_ANT_DIV_MODE_MANUAL 0x01 // !< Antenna is selected manually +#define NRF_802154_SL_ANT_DIV_MODE_AUTO 0x02 // !< Antenna is selected automatically based on RSSI - not supported for transmission. + +/** + * @brief Available antennas + * + * Possible values: + * - @ref NRF_802154_SL_ANT_DIV_ANTENNA_1, + * - @ref NRF_802154_SL_ANT_DIV_ANTENNA_2, + * - @ref NRF_802154_SL_ANT_DIV_ANTENNA_NONE + */ +typedef uint8_t nrf_802154_sl_ant_div_antenna_t; + +#define NRF_802154_SL_ANT_DIV_ANTENNA_1 0x00 // !< First antenna +#define NRF_802154_SL_ANT_DIV_ANTENNA_2 0x01 // !< Second antenna +#define NRF_802154_SL_ANT_DIV_ANTENNA_NONE 0x02 // !< Used to indicate that antenna for the last reception was not selected via antenna diversity algorithm. + +/** + * @brief Types of operations supported by antenna diversity module. + * + * Possible values: + * - @ref NRF_802154_SL_ANT_DIV_OP_RX, + * - @ref NRF_802154_SL_ANT_DIV_OP_TX + */ +typedef uint8_t nrf_802154_sl_ant_div_op_t; + +#define NRF_802154_SL_ANT_DIV_OP_RX 0x00 // !< RX-related operations +#define NRF_802154_SL_ANT_DIV_OP_TX 0x01 // !< TX-related operations + +/** + * @brief Configuration of the antenna diversity module. + * + * The following configuration parameters are to be set before + * @ref nrf_802154_sl_ant_div_init is called. + */ +typedef struct +{ + /** + * @brief Pin used for antenna selection. + */ + uint8_t ant_sel_pin; + + /** + * @brief Time in microseconds between antenna switches in @ref NRF_802154_SL_ANT_DIV_MODE_AUTO. + */ + uint8_t toggle_time; + + /** + * @brief PPI channel instance used to connect TIMER event with antenna toggling task. + * + * Antenna diversity interface claims exclusive access to the provided PPI channel. + */ + uint8_t ppi_ch; + + /** + * @brief GPIOTE channel instance used to toggle antenna when triggered with PPI. + * + * Antenna diversity interface claims exclusive access to the provided GPIOTE channel. + */ + uint8_t gpiote_ch; + + /** + * @brief Timer instance used to measure time between consecutive antenna toggles. + * + * Antenna diversity interface claims exclusive access to the provided TIMER peripheral. + */ + NRF_TIMER_Type * p_timer; +} nrf_802154_sl_ant_div_cfg_t; + +/** + * @} + * @defgroup nrf_802154_ant_div_cfg Antenna diversity configuration + * @{ + */ + +/** + * @brief Configures the antenna diversity interface. + * + * @note This function must be called before @ref nrf_802154_sl_ant_div_init + * and can only be called once. + * + * @param[in] p_cfg Antenna diversity interface configuration. + */ +void nrf_802154_sl_ant_div_cfg_set(const nrf_802154_sl_ant_div_cfg_t * p_cfg); + +/** + * @brief Gets the antenna diversity interface configuration. + * + * @param[out] p_cfg Antenna diversity interface configuration. + * + * @retval true The configuration was retrieved successfully. + * @retval false The configuration could not be retrieved. + */ +bool nrf_802154_sl_ant_div_cfg_get(nrf_802154_sl_ant_div_cfg_t * p_cfg); + +/** + * @brief Sets the antenna diversity mode. + * + * @param[in] op Type of antenna diversity operations the mode should be changed for. + * @param[in] mode Antenna diversity mode to be set. + * + * @retval true Antenna diversity mode set successfully. + * @retval false Invalid antenna diversity mode or operation type passed as arguments. + */ +bool nrf_802154_sl_ant_div_cfg_mode_set(nrf_802154_sl_ant_div_op_t op, + nrf_802154_sl_ant_div_mode_t mode); + +/** + * @brief Gets the antenna diversity mode. + * + * @param[in] op Type of antenna diversity operations the mode should be retrieved for. + * + * @return Current antenna diversity mode. + */ +nrf_802154_sl_ant_div_mode_t nrf_802154_sl_ant_div_cfg_mode_get(nrf_802154_sl_ant_div_op_t op); + +/** + * @brief Selects antenna to be used in @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL mode. + * + * @note Takes effect only if antenna diversity mode is set to + * @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. See @ref nrf_802154_sl_ant_div_mode_set. + * + * @param[in] op Type of antenna diversity operations the antenna should be changed for. + * @param[in] antenna Antenna to be selected. + * + * @retval true Antenna selected successfully. + * @retval false Invalid antenna or operation type passed as arguments. + */ +bool nrf_802154_sl_ant_div_cfg_antenna_set(nrf_802154_sl_ant_div_op_t op, + nrf_802154_sl_ant_div_antenna_t antenna); + +/** + * @brief Reads the currently used antenna. + * + * @note The antenna read by this function is currently used antenna only if antenna diversity + * mode is set to @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise, currently used antenna + * may be different. @sa nrf_802154_sl_ant_div_mode_set + * + * @param[in] op Type of antenna diversity operations the antenna should be retrieved for. + * + * @return Currently selected antenna. + */ +nrf_802154_sl_ant_div_antenna_t nrf_802154_sl_ant_div_cfg_antenna_get( + nrf_802154_sl_ant_div_op_t op); + +/** + * @} + * @defgroup nrf_802154_ant_div Antenna diversity API + * @{ + */ + +/** + * @brief Initializes antenna diversity module. + * + * @note Before this function is called, antenna diversity interface must be configured with + * @ref nrf_802154_sl_ant_div_cfg_set. + * + * @retval true Initialization was successful. + * @retval false Initialization could not be performed due to unconfigured interface. + */ +bool nrf_802154_sl_ant_div_init(void); + +/** + * @brief Selects an antenna to use. + * + * This function has no effect if called when antenna diversity module is toggling antenna, i.e.: + * - @ref NRF_802154_SL_ANT_DIV_MODE_AUTO is set + * - receiver is turned on + * - no PPDU is currently being received + * + * @param[in] antenna Antenna to be used. + * + * @retval true Antenna switched successfully. + * @retval false Invalid antenna passed to the function. + */ +bool nrf_802154_sl_ant_div_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna); + +/** + * @brief Gets currently used antenna. + * + * @retval NRF_802154_SL_ANT_DIV_ANTENNA_1 If antenna 1 is used. + * @retval NRF_802154_SL_ANT_DIV_ANTENNA_2 If antenna 2 is used. + * @retval NRF_802154_SL_ANT_DIV_ANTENNA_NONE If the antenna diversity interface is not configured. + */ +nrf_802154_sl_ant_div_antenna_t nrf_802154_sl_ant_div_antenna_get(void); + +/** + * @brief Gets which antenna was selected as best for the last reception. + * + * @note In three cases @ref NRF_802154_SL_ANT_DIV_ANTENNA_NONE may be returned: + * - No frame was received yet. + * - Last frame was received with antenna diversity auto mode disabled. + * - RSSI measurements didn't have enough time to finish during last frame reception + * and it is unspecified which antenna was selected. + * + * @return Antenna selected during last successful reception in automatic mode. + */ +nrf_802154_sl_ant_div_antenna_t nrf_802154_sl_ant_div_last_rx_best_antenna_get(void); + +/** + * @brief Handles TIMER IRQ of the antenna diversity interface. + * + * This function should be called when the timer instance provided to the antenna diversity + * interface reports an interrupt. + */ +void nrf_802154_sl_ant_div_timer_irq_handle(void); + +/** + * @} + * @defgroup nrf_802154_ant_div_callout Antenna diversity callouts + * @{ + */ + +/** + * @brief Callout for RSSI measurement. + * + * RSSI needs to be settled already after enabling RX or switching antenna. + * + * @note This function must be called from critical section. + * + * @return Corrected measured RSSI value. + */ +extern int8_t nrf_802154_sl_ant_div_rssi_measure_get(void); + +/** + * @} + * @defgroup nrf_802154_ant_div_notification Antenna diversity notifications + * @{ + */ + +/** + * @brief Notification to be called when antenna diversity auto mode is enabled. + */ +void nrf_802154_sl_ant_div_rx_auto_mode_enable_notify(void); + +/** + * @brief Notification to be called when antenna diversity auto mode is disabled. + */ +void nrf_802154_sl_ant_div_rx_auto_mode_disable_notify(void); + +/** + * @brief Notification to be called when radio rx is started. + */ +void nrf_802154_sl_ant_div_rx_started_notify(void); + +/** + * @brief Notification to be called when radio rx is aborted. + */ +void nrf_802154_sl_ant_div_rx_aborted_notify(void); + +/** + * @brief Notification to be called when preamble is detected. + */ +void nrf_802154_sl_ant_div_rx_preamble_detected_notify(void); + +/** + * @brief Notification to be called when frame start is detected during reception. + * + * @retval true RSSI measurements have finished and currently selected antenna is optimal for reception. + * @retval false RSSI measurements have not yet finished and currently selected antenna is random. + */ +bool nrf_802154_sl_ant_div_rx_frame_started_notify(void); + +/** + * @brief Notification to be called when frame is received successfuly. + */ +void nrf_802154_sl_ant_div_rx_frame_received_notify(void); + +/** + * @brief Notification to be called when timeout expires after preamble detection. + */ +void nrf_802154_sl_ant_div_rx_preamble_timeout_notify(void); + +/** + * @brief Notification to be called when energy detection procedure is requested. + * + * This notification will update the antenna and inform the caller for how long the energy + * detection operation should be scheduled. This notification should also be called + * after @ref nrf_802154_sl_ant_div_energy_detection_finished_notify requests repeating + * the energy detection procedure. In that case, p_ed_time value must be set to 0 + * when passed to the function. + * + * @param[inout] p_ed_time Time of the energy detection procedure requested. Value will be updated with time for + * energy detection procedure on the current antenna. + */ +void nrf_802154_sl_ant_div_energy_detection_requested_notify(uint32_t * p_ed_time); + +/** + * @brief Notification to be called when energy detection procedure is finished. + * This notification checks whether the procedure should be repeated on the second antenna. + * + * @retval true Energy detection should be repeated, antenna diversity module will switch the antenna when it is started. + * @retval false Energy detection is finished, the result can be reported as normally. + */ +bool nrf_802154_sl_ant_div_energy_detection_finished_notify(void); + +/** + * @brief Notification to be called when energy detection procedure is aborted. + */ +void nrf_802154_sl_ant_div_energy_detection_aborted_notify(void); + +/** + * @brief Notification to be called when txack operation is requested. + */ +void nrf_802154_sl_ant_div_txack_notify(void); + +#endif // NRF_802154_SL_ANT_DIV_H diff --git a/nrf_802154_sl/include/nrf_802154_sl_coex.h b/nrf_802154_sl/include/nrf_802154_sl_coex.h new file mode 100644 index 0000000..56c34bc --- /dev/null +++ b/nrf_802154_sl/include/nrf_802154_sl_coex.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_802154_SL_COEX_H__ +#define NRF_802154_SL_COEX_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_802154_sl_coex Wifi Coexistence Service + * @{ + * @ingroup nrf_802154_sl_coex + * @brief The Wifi Coexistence Service for the 802.15.4 Service Layer + */ + +/** @brief Coex return codes. + * + * Possible values: + * @ref NRF_802154_WIFI_COEX_RET_SUCCESS + * @ref NRF_802154_WIFI_COEX_RET_INVALID_PIN + * @ref NRF_802154_WIFI_COEX_RET_DEFAULT_ERR + */ + +typedef uint32_t nrf_802154_wifi_coex_ret_t; + +#define NRF_802154_WIFI_COEX_RET_SUCCESS 0x00 /** Operation finished succesfully. */ +#define NRF_802154_WIFI_COEX_RET_INVALID_PIN 0x01 /** Operation failed because coex pins have not been initialized. */ +#define NRF_802154_WIFI_COEX_RET_DEFAULT_ERR 0xFF /** Default error code. */ + +/** @brief Coex interface types. + * + * Possible values: + * @ref NRF_802154_WIFI_COEX_IF_NONE + * @ref NRF_802154_WIFI_COEX_IF_3WIRE + */ +typedef uint32_t nrf_802154_wifi_coex_interface_type_id_t; + +#define NRF_802154_WIFI_COEX_IF_NONE 0x00 /** No coex interface is selected */ +#define NRF_802154_WIFI_COEX_IF_3WIRE 0x01 /** 3-wire coex interface is selected */ + +/**@brief Pin configuration for wifi coex */ +typedef struct +{ + uint8_t gpio_pin; /**< The GPIO pin number. */ + uint8_t active_high; /**< Active pin level: 1 - high level, 0 - low level. */ + uint8_t drive; /**< Pin drive configuration. */ + uint8_t pull; /**< Pull-up/down configuration. */ +} nrf_802154_wifi_coex_pin_out_config_t; + +typedef struct +{ + uint8_t gpio_pin; /**< The GPIO pin number. */ + uint8_t active_high; /**< Active pin level: 1 - high level, 0 - low level. */ + uint8_t gpiote_ch_id; /**< GPIOTE channel number. */ +} nrf_802154_wifi_coex_pin_in_config_t; + +/**@brief 3-wire interface configuration for wifi coex */ +typedef struct +{ + nrf_802154_wifi_coex_pin_out_config_t request_cfg; /**< Request line configuration. */ + nrf_802154_wifi_coex_pin_out_config_t priority_cfg; /**< Priority and Status (sometiems also called CONFIG or REQUEST_TYPE) line configuration. */ + nrf_802154_wifi_coex_pin_in_config_t grant_cfg; /**< Grant line configuration. */ +} nrf_802154_wifi_coex_3wire_if_config_t; + +#define COEX_GPIO_PIN_INVALID 0xFF /**< Value indicating that the pin has not yet been configured. */ + +/** Macro with the default configuration of 3-wire coex interface */ +#define NRF_802154_COEX_3WIRE_DEFAULT_CONFIG \ + ((nrf_802154_wifi_coex_3wire_if_config_t) { \ + .request_cfg = { \ + .gpio_pin = COEX_GPIO_PIN_INVALID, \ + .active_high = true, \ + .drive = GPIO_PIN_CNF_DRIVE_S0S1, \ + .pull = GPIO_PIN_CNF_PULL_Disabled \ + }, \ + .priority_cfg = { \ + .gpio_pin = COEX_GPIO_PIN_INVALID, \ + .active_high = false, \ + .drive = GPIO_PIN_CNF_DRIVE_S0S1, \ + .pull = GPIO_PIN_CNF_PULL_Disabled \ + }, \ + .grant_cfg = { \ + .gpio_pin = COEX_GPIO_PIN_INVALID, \ + .active_high = false, \ + .gpiote_ch_id = 4 \ + } \ + }) + +/** + * @brief Gets current coex interface type. + * + * @return Current coex interface type. + */ +nrf_802154_wifi_coex_interface_type_id_t nrf_802154_wifi_coex_interface_type_id_get(void); + +/** + * @brief Gets current wifi coex 3wire configuration. + * + * @param[out] p_cfg Pointer to the configuration structure where current configuration will be stored. + */ +void nrf_802154_wifi_coex_cfg_3wire_get(nrf_802154_wifi_coex_3wire_if_config_t * p_cfg); + +/** + * @brief Sets wifi coex 3wire configuration. + * + * For the configuration to be applied, @ref nrf_802154_wifi_coex_init must be called. + * Should be called once, before @ref nrf_802154_wifi_coex_init. + * + * @param[in] p_cfg Pointer to the configuration structure with coex configuration to be set. + * Structure will be copied and can be freed by the caller afterwards. + * + * @sa nrf_802154_wifi_coex_cfg_3wire_get + */ +void nrf_802154_wifi_coex_cfg_3wire_set(const nrf_802154_wifi_coex_3wire_if_config_t * p_cfg); + +/** + * @brief Initializes the Wi-Fi Coexistence module. + * + * For this function to be called, driver needs to be already initialized through @ref nrf_802154_init, and interface type with valid pins + * must be configured. + * + * @retval ::NRF_802154_WIFI_COEX_RET_SUCCESS Coexistence interface was configured successfully + * @retval ::NRF_802154_WIFI_COEX_RET_INVALID_PIN Not all gpio pin numbers have been set and coexistence interface could not be configured. + */ +nrf_802154_wifi_coex_ret_t nrf_802154_wifi_coex_init(void); + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_802154_SL_COEX_H__ diff --git a/nrf_802154_sl/include/nrf_802154_sl_config.h b/nrf_802154_sl/include/nrf_802154_sl_config.h new file mode 100644 index 0000000..a7bc680 --- /dev/null +++ b/nrf_802154_sl/include/nrf_802154_sl_config.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file This file implements the nRF 802.15.4 Service Layer configuration options. + * + */ + +#ifndef NRF_802154_SL_CONFIG_H__ +#define NRF_802154_SL_CONFIG_H__ + +/** + * @def NRF_802154_SL_COEX_INITIALLY_ENABLED + * + * Configures if WiFi Coex is initially enabled or disabled. + */ +#ifndef NRF_802154_SL_COEX_INITIALLY_ENABLED +#define NRF_802154_SL_COEX_INITIALLY_ENABLED 0 +#endif + +/** + * @def NRF_802154_SL_RTC_IRQ_PRIORITY + * + * The priority of RTC interrupt used in the standalone timer driver implementation. + * + * @note This configuration is only applicable for the Low Power Timer Abstraction Layer + * implementation in nrf_802154_lp_timer_nodrv.c. + * + */ +#ifndef NRF_802154_SL_RTC_IRQ_PRIORITY +#define NRF_802154_SL_RTC_IRQ_PRIORITY 5 +#endif + +/** + * @def NRF_802154_SL_TIMESTAMP_ENABLED + * + * Configures if timestamps are to be added to the requested events. + */ +#ifndef NRF_802154_SL_TIMESTAMP_ENABLED +#define NRF_802154_SL_TIMESTAMP_ENABLED 1 +#endif + +#endif // NRF_802154_SL_CONFIG_H__ diff --git a/nrf_802154_sl/include/nrf_802154_sl_fault.h b/nrf_802154_sl/include/nrf_802154_sl_fault.h new file mode 100644 index 0000000..3af9e03 --- /dev/null +++ b/nrf_802154_sl/include/nrf_802154_sl_fault.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief 802.15.4 SL fault handler module. + */ + +#ifndef NRF_802154_SL_FAULT_H__ +#define NRF_802154_SL_FAULT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * @brief Function called when an unrecoverable runtime error occurs. + * + * @param[in] module_id Identifier of the module that triggered the error. + * @param[in] line Line that triggered the error. + * @param[in] p_error String that contains the error. + */ +extern void nrf_802154_sl_fault_handler(uint32_t module_id, int32_t line, const char * p_error); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_802154_SL_FAULT_H__ diff --git a/nrf_802154_sl/include/nrf_802154_sl_log.h b/nrf_802154_sl/include/nrf_802154_sl_log.h new file mode 100644 index 0000000..72915ff --- /dev/null +++ b/nrf_802154_sl/include/nrf_802154_sl_log.h @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * @defgroup nrf_802154_sl_debug_logging Debug logging service + * @{ + * @ingroup nrf_802154 + * @brief Execution backtrace and internal events logging service. + * + * To obtain unambiguous output of debug logs, it is required to use a unique identifier + * in each @c .c module. See the following distribution of IDs for debug logs in component libraries: + * - ranges for .c modules: + * - [ 1 .. 31 ] for 802.15.4 Driver modules (NRF_802154_DRV_MODULE_ID_..) + * - [ 32 .. 39 ] for 802.15.4 MPSL modules (NRF_802154_MPSL_MODULE_ID_..) + * - [ 40 .. 63 ] for 802.15.4 SL modules (NRF_802154_SL_MODULE_ID_..) + * - ranges for global events (NRF_802154_LOG_GLOBAL_EVENT_ID_..) : + * - [ 1 .. 31 ] for global events in 802.15.4 Driver + * - [ 32 .. 39 ] for global events in 802.15.4 MPSL + * - [ 40 .. 63 ] for global events in 802.15.4 SL + * + */ + +#ifndef NRF_802154_SL_LOG_H__ +#define NRF_802154_SL_LOG_H__ + +#include + +/**@def NRF_802154_SL_DEBUG_LOG_BUFFER_LEN + * @brief Configures capacity of debug log buffer. + * + * The value of this macro determines how many entries can be stored in the log buffer. + * If the buffer capacity is exceeded, the oldest entries are overwritten. + * + * @note This value must be power of 2. + */ +#ifndef NRF_802154_SL_DEBUG_LOG_BUFFER_LEN +#define NRF_802154_SL_DEBUG_LOG_BUFFER_LEN 1024U +#endif + +/**@def NRF_802154_SL_DEBUG_LOG_BLOCKS_INTERRUPTS + * @brief Configures if writing to log buffer is performed with interrupts disabled. + * + * Setting this macro to 1 has following consequences: + * - Interrupts are automatically disabled during write to log buffer. This ensures + * thread-safety and always coherent log. + * - Higher priority interrupts may be delayed, so logging has impact on timing. + * + * Setting this macro to 0 has following consequences: + * - Interrupts are NOT disabled during write to log buffer. This may lead to missing + * logs if higher priority interrupt preempts current write log operation. + * - Logging does not introduce delay to execution of higher priority interrupts. + */ +#ifndef NRF_802154_SL_DEBUG_LOG_BLOCKS_INTERRUPTS +#define NRF_802154_SL_DEBUG_LOG_BLOCKS_INTERRUPTS 0 +#endif + +/**@def NRF_802154_SL_LOG_VERBOSITY + * @brief Defines the verbosity level of generated logs. + * + * Define this macro in your @c .c file before inclusion of @c nrf_802154_debug_log.h to + * set verbosity level per-module basis. + */ +#ifndef NRF_802154_SL_LOG_VERBOSITY +#define NRF_802154_SL_LOG_VERBOSITY NRF_802154_LOG_VERBOSITY_LOW +#endif + +#define NRF_802154_LOG_VERBOSITY_NONE 0 +#define NRF_802154_LOG_VERBOSITY_LOW 1 +#define NRF_802154_LOG_VERBOSITY_HIGH 2 + +#if (NRF_802154_SL_DEBUG_LOG_BLOCKS_INTERRUPTS) + +#include "nrf_802154_sl_utils.h" + +/**@brief Declares a variable for storing interrupts state before disabling interrupts. */ +#define nrf_802154_sl_debug_log_saved_interrupt_st_variable(var_name) \ + nrf_802154_sl_mcu_critical_state_t var_name + +#define nrf_802154_sl_debug_log_disable_interrupts(var_name) \ + nrf_802154_sl_mcu_critical_enter(var_name) \ + +#define nrf_802154_sl_debug_log_restore_interrupts(var_name) \ + nrf_802154_sl_mcu_critical_exit(var_name) \ + +#else + +#define nrf_802154_sl_debug_log_saved_interrupt_st_variable(var_name) /* empty macro */ + +#define nrf_802154_sl_debug_log_disable_interrupts(var_name) \ + do \ + { \ + } \ + while (0) + +#define nrf_802154_sl_debug_log_restore_interrupts(var_name) \ + do \ + { \ + } \ + while (0) + +#endif + +/**@brief Checks if the provided @p verbosity parameter has a value that allows the module to record a log. */ +#define nrf_802154_sl_log_verbosity_allows(verbosity) \ + (((verbosity) > 0) && ((verbosity) <= NRF_802154_SL_LOG_VERBOSITY)) + +#if !defined(CU_TEST) && (NRF_802154_SL_ENABLE_DEBUG_LOG) + +extern volatile uint32_t g_nrf_802154_sl_log_buffer[NRF_802154_SL_DEBUG_LOG_BUFFER_LEN]; +extern volatile uint32_t gp_nrf_802154_sl_log_ptr; + +/**@brief Writes one word into debug log buffer. */ +#define nrf_802154_sl_debug_log_write_raw(value) \ + do \ + { \ + uint32_t nrf_802154_sl_debug_log_wr_raw_value = (value); \ + \ + nrf_802154_sl_debug_log_saved_interrupt_st_variable(nrf_802154_sl_debug_log_wr_raw_sv); \ + nrf_802154_sl_debug_log_disable_interrupts(nrf_802154_sl_debug_log_wr_raw_sv); \ + \ + uint32_t nrf_802154_sl_debug_log_write_raw_ptr = gp_nrf_802154_sl_log_ptr; \ + \ + g_nrf_802154_sl_log_buffer[nrf_802154_sl_debug_log_write_raw_ptr] = \ + nrf_802154_sl_debug_log_wr_raw_value; \ + nrf_802154_sl_debug_log_write_raw_ptr += 1U; \ + nrf_802154_sl_debug_log_write_raw_ptr &= (NRF_802154_SL_DEBUG_LOG_BUFFER_LEN - 1U); \ + gp_nrf_802154_sl_log_ptr = nrf_802154_sl_debug_log_write_raw_ptr; \ + \ + nrf_802154_sl_debug_log_restore_interrupts(nrf_802154_sl_debug_log_wr_raw_sv); \ + } \ + while (0) + +#else // !defined(CU_TEST) && (NRF_802154_SL_ENABLE_DEBUG_LOG) + +#define nrf_802154_sl_debug_log_write_raw(value) \ + do \ + { \ + } \ + while (0) + +#endif // !defined(CU_TEST) && (NRF_802154_SL_ENABLE_DEBUG_LOG) + +/**@name nrf_802154_sl_debug_log_entry_types + * @brief Types of log entries. + * + * Value 0 is reserved and can't be used (reserved for empty log entry). + * Allowed values are in range [ 1 .. 15 ]. + * + * @{ + */ +#define NRF_802154_LOG_TYPE_FUNCTION_ENTER 1U +#define NRF_802154_LOG_TYPE_FUNCTION_EXIT 2U +#define NRF_802154_LOG_TYPE_LOCAL_EVENT 3U +#define NRF_802154_LOG_TYPE_GLOBAL_EVENT 4U +/** + *@} + **/ + +/**@brief Bit shift of field "log type" in log word. */ +#define NRF_802154_SL_DEBUG_LOG_TYPE_BITPOS 28 + +/**@brief Bit shift of field "module id" in log word. */ +#define NRF_802154_SL_DEBUG_LOG_MODULE_ID_BITPOS 22 + +/**@brief Bit shift of field "event id" in log word. */ +#define NRF_802154_SL_DEBUG_LOG_EVENT_ID_BITPOS 16 + +/**@brief Records log about entry to a function. + * + * @param[in] verbosity Verbosity level required to emit log. + */ +#define nrf_802154_sl_log_function_enter(verbosity) \ + do \ + { \ + if (nrf_802154_sl_log_verbosity_allows(verbosity)) \ + { \ + nrf_802154_sl_debug_log_write_raw( \ + ((NRF_802154_LOG_TYPE_FUNCTION_ENTER) << NRF_802154_SL_DEBUG_LOG_TYPE_BITPOS) | \ + ((NRF_802154_MODULE_ID) << NRF_802154_SL_DEBUG_LOG_MODULE_ID_BITPOS) | \ + ((uint32_t)((uintptr_t)(__func__)) << 0)); \ + } \ + } \ + while (0) + +/**@brief Records log about exit from a function. + * + * @param[in] verbosity Verbosity level required to emit log. + */ +#define nrf_802154_sl_log_function_exit(verbosity) \ + do \ + { \ + if (nrf_802154_sl_log_verbosity_allows(verbosity)) \ + { \ + nrf_802154_sl_debug_log_write_raw( \ + ((NRF_802154_LOG_TYPE_FUNCTION_EXIT) << NRF_802154_SL_DEBUG_LOG_TYPE_BITPOS) | \ + ((NRF_802154_MODULE_ID) << NRF_802154_SL_DEBUG_LOG_MODULE_ID_BITPOS) | \ + ((uint32_t)((uintptr_t)(__func__)) << 0)); \ + } \ + } \ + while (0) + +/**@brief Records log about event (with parameter) related to current module. + * + * @param[in] verbosity Verbosity level required to emit log. + * @param[in] local_event_id Event identifier whose meaning is defined within the scope + * of the module. Possible values: [ 0 .. 63 ]. + * @param[in] param_u16 Additional parameter to be logged with event. Meaning + * of the parameter is defined by the module in which + * the log is recorded and @p local_event_id. + */ +#define nrf_802154_sl_log_local_event(verbosity, local_event_id, param_u16) \ + do \ + { \ + if (nrf_802154_sl_log_verbosity_allows(verbosity)) \ + { \ + nrf_802154_sl_debug_log_write_raw( \ + ((NRF_802154_LOG_TYPE_LOCAL_EVENT) << NRF_802154_SL_DEBUG_LOG_TYPE_BITPOS) | \ + ((NRF_802154_MODULE_ID) << NRF_802154_SL_DEBUG_LOG_MODULE_ID_BITPOS) | \ + (((uint32_t)(local_event_id)) << NRF_802154_SL_DEBUG_LOG_EVENT_ID_BITPOS) | \ + ((uint16_t)(param_u16) << 0)); \ + } \ + } \ + while (0) + +/**@brief Records log about event (with parameter) related to global resource. + * + * @param[in] verbosity Verbosity level required to emit log. + * @param[in] event_id Event identifier whose meaning is defined globally. Possible values: [ 0 .. 63 ]. + * @param[in] param_u16 Additional parameter to be logged with event. Meaning + * of the parameter is defined by value of @p global_event_id. + */ +#define nrf_802154_sl_log_global_event(verbosity, global_event_id, param_u16) \ + do \ + { \ + if (nrf_802154_sl_log_verbosity_allows(verbosity)) \ + { \ + nrf_802154_sl_debug_log_write_raw( \ + ((NRF_802154_LOG_TYPE_GLOBAL_EVENT) << NRF_802154_SL_DEBUG_LOG_TYPE_BITPOS) | \ + ((NRF_802154_MODULE_ID) << NRF_802154_SL_DEBUG_LOG_MODULE_ID_BITPOS) | \ + (((uint32_t)(global_event_id)) << NRF_802154_SL_DEBUG_LOG_EVENT_ID_BITPOS) | \ + ((uint16_t)(param_u16) << 0)); \ + } \ + } \ + while (0) + +/**@brief Helper macro for defining one element of the list of local events. + * + * @param[in] module_lbl name of module + * @param[in] event_lbl name of local event + * @param[in] event_id numeric id of local event (unique in module @c module_lbl) + * @param[in] event_enum enum that defines the set of possible values of parameter + for event @c event_lbl + */ +#define NRF_802154_LOG_L_EVENT_DEFINE(module_lbl, event_lbl, event_id, event_enum) \ + NRF_802154_LOG_LOCAL_EVENT_ID_ ## module_lbl ## __ ## event_lbl = event_id, \ + NRF_802154_LOG_LE ## event_id ## _PARAM_ENUM_ ## event_enum = event_id, + +/** + * @brief Initializes the Debug Logs module. + * + */ +void nrf_802154_sl_log_init(void); + +/** + *@} + **/ + +#endif // NRF_802154_SL_LOG_H__ diff --git a/nrf_802154_sl/include/nrf_802154_sl_periphs.h b/nrf_802154_sl/include/nrf_802154_sl_periphs.h new file mode 100644 index 0000000..cd3e7e8 --- /dev/null +++ b/nrf_802154_sl/include/nrf_802154_sl_periphs.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file Module that defines the 802.15.4 driver peripheral usage. + * + */ + +#ifndef NRF_802154_SL_PERIPHS_H__ +#define NRF_802154_SL_PERIPHS_H__ + +#include +#include +#include "hal/nrf_ppi.h" + +/** + * @def NRF_802154_RTC_INSTANCE_NO + * + * Number of the RTC instance used in the standalone timer driver implementation. + * + */ +#ifndef NRF_802154_RTC_INSTANCE_NO + +#if defined(NRF52811_XXAA) || defined(NRF52820_XXAA) +#define NRF_802154_RTC_INSTANCE_NO 0 +#else +#define NRF_802154_RTC_INSTANCE_NO 2 +#endif + +#endif // NRF_802154_RTC_INSTANCE_NO + +/** + * @def NRF_802154_RTC_INSTANCE + * + * The RTC instance used in the standalone timer driver implementation. + * + * @note This configuration is only applicable for the Low Power Timer Abstraction Layer + * implementation in nrf_802154_lp_timer_nodrv.c. + * + */ +#define NRF_802154_RTC_INSTANCE NRFX_CONCAT_2(NRF_RTC, NRF_802154_RTC_INSTANCE_NO) + +/** + * @def NRF_802154_RTC_IRQ_HANDLER + * + * The RTC interrupt handler name used in the standalone timer driver implementation. + * + * @note This configuration is only applicable for Low Power Timer Abstraction Layer implementation + * in nrf_802154_lp_timer_nodrv.c. + * + */ +#define NRF_802154_RTC_IRQ_HANDLER NRFX_CONCAT_3(RTC, NRF_802154_RTC_INSTANCE_NO, _IRQHandler) + +/** + * @def NRF_802154_RTC_IRQN + * + * The RTC Interrupt number used in the standalone timer driver implementation. + * + * @note This configuration is only applicable for the Low Power Timer Abstraction Layer implementation + * in nrf_802154_lp_timer_nodrv.c. + * + */ +#define NRF_802154_RTC_IRQN NRFX_CONCAT_3(RTC, NRF_802154_RTC_INSTANCE_NO, _IRQn) + +/** + * @def NRF_802154_HIGH_PRECISION_TIMER_INSTANCE_NO + * + * Number of the timer instance used for precise frame timestamps and synchronous radio operations. + * + */ +#ifndef NRF_802154_HIGH_PRECISION_TIMER_INSTANCE_NO +#define NRF_802154_HIGH_PRECISION_TIMER_INSTANCE_NO 0 +#endif + +/** + * @def NRF_802154_HIGH_PRECISION_TIMER_INSTANCE + * + * The timer instance used for precise frame timestamps and synchronous radio operations. + * + */ +#define NRF_802154_HIGH_PRECISION_TIMER_INSTANCE \ + NRFX_CONCAT_2(NRF_TIMER, NRF_802154_HIGH_PRECISION_TIMER_INSTANCE_NO) + +/** + * @def NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE + * + * The PPI channel that connects LP timer's COMPARE event to HP timer's TIMER_CAPTURE task. + * + * @note This option is used only when the timestamping feature is enabled + * (see @ref NRF_802154_SL_TIMESTAMP_ENABLED). + * + */ +#ifndef NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE +#define NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE NRF_PPI_CHANNEL13 +#endif + +/** + * @def NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE + * + * The PPI channel that connects provided event to HP timer's TIMER_CAPTURE task. + * + * @note This option is used only when the timestamping feature is enabled + * (see @ref NRF_802154_SL_TIMESTAMP_ENABLED). + * + */ +#ifndef NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE +#define NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE NRF_PPI_CHANNEL14 +#endif + +/** + * @def NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK + * + * Helper bit mask of PPI channels used by the 802.15.4 driver for timestamping. + */ +#define NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK \ + ((1 << NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE) | \ + (1 << NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE)) + +/** + * @def NRF_802154_PPI_TIMESTAMP_GROUP + * + * The PPI channel group used to control PPIs used for timestamping. + * + * @note This option is used only when the timestamping feature is enabled + * (see @ref NRF_802154_SL_TIMESTAMP_ENABLED). + * + */ +#ifndef NRF_802154_PPI_TIMESTAMP_GROUP +#define NRF_802154_PPI_TIMESTAMP_GROUP NRF_PPI_CHANNEL_GROUP2 +#endif + +#endif // NRF_802154_SL_PERIPHS_H__ diff --git a/nrf_802154_sl/include/nrf_802154_sl_rsch.h b/nrf_802154_sl/include/nrf_802154_sl_rsch.h new file mode 100644 index 0000000..2a28b7f --- /dev/null +++ b/nrf_802154_sl/include/nrf_802154_sl_rsch.h @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_802154_SL_RSCH_H__ +#define NRF_802154_SL_RSCH_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_802154_sl_rsch Resource Scheduler Service + * @{ + * @ingroup nrf_802154_sl_rsch + * @brief The Resource Scheduler Service for the 802.15.4 Service Layer + */ + +#define NRF_802154_SL_RSCH_TS_PRIORITY_LOWEST 0U /**< Lowest possible priority of a timeslot. */ +#define NRF_802154_SL_RSCH_SESSION_PRIV_SIZE 1U /**< Number of words needed for private fields of a session. */ +#define NRF_802154_SL_RSCH_DEFAULT_MARGIN_US 100U /**< Default margin in microseconds. Refer to @ref nrf_802154_sl_rsch_ts_param_t. */ + +/** @brief Scheduler's return codes. + * + * Possible values: + * @ref NRF_802154_SL_RSCH_RET_SUCCESS + * @ref NRF_802154_SL_RSCH_RET_ALREADY_REQUESTED + * @ref NRF_802154_SL_RSCH_RET_INVALID_PARAM + * @ref NRF_802154_SL_RSCH_RET_HIGHER_PRIO + * @ref NRF_802154_SL_RSCH_RET_RSRC_DENIED + * @ref NRF_802154_SL_RSCH_RET_TIMESLOT_INACTIVE + * @ref NRF_802154_SL_RSCH_RET_DURATION_TIMEOUT + * @ref NRF_802154_SL_RSCH_RET_NO_MEMORY + + */ +typedef uint32_t nrf_802154_sl_rsch_ret_t; + +#define NRF_802154_SL_RSCH_RET_SUCCESS 0U /**< Operation finished successfully. */ +#define NRF_802154_SL_RSCH_RET_ALREADY_REQUESTED 1U /**< Operation failed because there is an already requested timeslot. */ +#define NRF_802154_SL_RSCH_RET_INVALID_PARAM 2U /**< Operation failed because the provided parameters are invalid. */ +#define NRF_802154_SL_RSCH_RET_HIGHER_PRIO 3U /**< Operation failed because of a higher priority request that overlaps in time. */ +#define NRF_802154_SL_RSCH_RET_RSRC_DENIED 4U /**< Operation failed because of a denied resource. */ +#define NRF_802154_SL_RSCH_RET_TIMESLOT_INACTIVE 5U /**< Operation failed because the timeslot's state does not allow it. */ +#define NRF_802154_SL_RSCH_RET_DURATION_TIMEOUT 6U /**< Operation finished because its requested duration expired. */ +#define NRF_802154_SL_RSCH_RET_NO_MEMORY 7U /**< Operation failed because there was no memory to complete it. */ + +/** @brief Flags indicating resources that can be accessed in a timeslot. + * + * This type is a mask of bits that represent access to different resources that may be necessary + * for successful operation inside a timeslot. + * + * Possible masks: + * @ref NRF_802154_SL_RSCH_RSRC_NONE + * @ref NRF_802154_SL_RSCH_RSRC_RADIO + * @ref NRF_802154_SL_RSCH_RSRC_RF + */ +typedef uint32_t nrf_802154_sl_rsch_resource_t; + +#define NRF_802154_SL_RSCH_RSRC_NONE 0U /**< Indicates that no resources are required. */ +#define NRF_802154_SL_RSCH_RSRC_RADIO (1 << 0) /**< Indicates that exclusive access to RADIO peripheral is required. */ +#define NRF_802154_SL_RSCH_RSRC_RF (1 << 1) /**< Indicates that exclusive access to radio wave medium is required. */ + +/** @brief Types 802.15.4 operations. + * + * Possible values: + * @ref NRF_802154_SL_RSCH_OP_NONE + * @ref NRF_802154_SL_RSCH_OP_LISTEN + * @ref NRF_802154_SL_RSCH_OP_RX + * @ref NRF_802154_SL_RSCH_OP_TX + */ +typedef uint32_t nrf_802154_sl_rsch_operation_t; + +#define NRF_802154_SL_RSCH_OP_NONE 0U /**< Non-802.15.4 related operation. */ +#define NRF_802154_SL_RSCH_OP_LISTEN 1U /**< 802.15.4 idle listening. */ +#define NRF_802154_SL_RSCH_OP_RX 2U /**< 802.15.4 active reception. */ +#define NRF_802154_SL_RSCH_OP_TX 3U /**< 802.15.4 transmission. */ + +/** @brief Structure that represents private fields of a session required by the implementation. */ +typedef struct +{ + uint32_t placeholder[NRF_802154_SL_RSCH_SESSION_PRIV_SIZE]; +} nrf_802154_sl_rsch_session_priv_placeholder_t; + +/** @brief Structure that represents the parameters of a session. */ +typedef struct +{ + nrf_802154_sl_rsch_session_priv_placeholder_t priv; +} nrf_802154_sl_rsch_session_t; + +/** @brief Structure that holds metadata passed in @ref nrf_802154_sl_rsch_ts_start_callback_t. + */ +typedef struct +{ + /** @brief Identifier of the started timeslot. */ + uint32_t ts_id; + + /** @brief Time in microseconds that the started timeslot is expected to last. */ + uint32_t duration_us; + + /** @brief Pointer to session that the started timeslot belongs to. */ + nrf_802154_sl_rsch_session_t * p_session; + +} nrf_802154_sl_rsch_ts_start_callback_metadata_t; + +/** @brief Structure that holds metadata passed in @ref nrf_802154_sl_rsch_ts_end_callback_t. + */ +typedef struct +{ + /** @brief Identifier of the ending timeslot. */ + uint32_t ts_id; + + /** @brief Return code that informs about the reason of timeslot end. */ + nrf_802154_sl_rsch_ret_t ret; + + /** @brief Pointer to resources that are to be handed over and do not require deconfiguration. + * + * When a timeslot is about to end, it's possible that there are other timeslots scheduled to + * occur immediately after it such that their required resources overlap with the resources + * requested by the ending timeslot. In order to avoid unnecessary deconfiguration + * and reconfiguration of resources that are continuously granted and required by consecutive + * timeslots, the scheduler fills this field with resources that need not be deconfigured + * upon the timeslot end so that they can be handed over to the following session. All remaining + * resources requested by the session must be deconfigured completely before + * @ref nrf_802154_sl_rsch_ts_release is called. + * + * @note If this field is set to NULL, all resources requested upon request must be deconfigured + * completely before @ref nrf_802154_sl_rsch_ts_release is called. + */ + nrf_802154_sl_rsch_resource_t * p_rsrc; + + /** @brief Pointer to session the ending timeslot belongs to. */ + nrf_802154_sl_rsch_session_t * p_session; + +} nrf_802154_sl_rsch_ts_end_callback_metadata_t; + +/** @brief Structure that holds metadata passed in @ref nrf_802154_sl_rsch_ts_cancelled_callback_t. */ +typedef struct +{ + /** @brief Identifier of the cancelled timeslot. */ + uint32_t ts_id; + + /** @brief Return code that informs about the reason of timeslot cancellation. */ + nrf_802154_sl_rsch_ret_t ret; + + /** @brief Pointer to session the cancelled timeslot belongs to. */ + nrf_802154_sl_rsch_session_t * p_session; + +} nrf_802154_sl_rsch_ts_cancelled_callback_metadata_t; + +/** @brief Structure that holds metadata passed in @ref nrf_802154_sl_rsch_ts_cleanup_callback_t. */ +typedef struct +{ + /** @brief Identifier of the timeslot that should be cleaned up. */ + uint32_t ts_id; + + /** @brief Pointer to resources that ought to be deconfigured. */ + nrf_802154_sl_rsch_resource_t * p_rsrc; + + /** @brief Pointer to session the timeslot belongs to. */ + nrf_802154_sl_rsch_session_t * p_session; + +} nrf_802154_sl_rsch_ts_cleanup_callback_metadata_t; + +/** @brief Function called by the scheduler to indicate that a requested timeslot has started. + * + * After this function is called, the session has exclusive access to the resources specified + * upon request. + * + * @param[in] p_context Pointer to data provided by the user. + * @param[in] p_metadata Pointer to data containing information regarding the started timeslot. + */ +typedef void (* nrf_802154_sl_rsch_ts_start_callback_t)( + void * p_context, nrf_802154_sl_rsch_ts_start_callback_metadata_t * p_metadata); + +/** @brief Function called by the scheduler to indicate that a requested and successfully started + * timeslot is about to end. + * + * The scheduler issues this call to occur when only a period of time specified upon timeslot + * request is left until the expected end of the timeslot. The call can be a result of a number + * of events, e.g. a preemption performed by a higher priority request, required resource denied + * by an external arbiter or timeout of the specified duration of the timeslot. After this function + * is called, the session is responsible for releasing exclusive access to the requested resources + * by calling @ref nrf_802154_sl_rsch_ts_release. Failing to do so in the specified time margin + * might result in blocking other 802.15.4 operations as well as other radio protocols. + * + * @param[in] p_context Pointer to data provided by the user. + * @param[in] p_metadata Pointer to data containing information regarding the ending timeslot. + */ +typedef void (* nrf_802154_sl_rsch_ts_end_callback_t)( + void * p_context, nrf_802154_sl_rsch_ts_end_callback_metadata_t * p_metadata); + +/** @brief Function called by the scheduler to indicate that a requested and not yet started + * timeslot was cancelled by the scheduler. + * + * This function is called when a successful request from the past is cancelled by the scheduler + * before the requested timeslot is started. The call can be a result of a higher priority timeslot + * requested for the same period of time or a required resource certain to be unavailable + * at the specified period of time. + * + * @param[in] p_context Pointer to data provided by the user. + * @param[in] p_metadata Pointer to data containing information regarding the cancelled timeslot. + */ +typedef void (* nrf_802154_sl_rsch_ts_cancelled_callback_t)( + void * p_context, nrf_802154_sl_rsch_ts_cancelled_callback_metadata_t * p_metadata); + +/** @brief Function called by the scheduler to indicate that a requested and not yet started + * timeslot requires deconfiguration of resources that were handed over to it. + * + * It might happen that a timeslot had had its resources handed over, but they became unavailable + * before the timeslot could start. Although the timeslot never starts, it must deconfigure + * the resources that were handed over to it and that were denied by the scheduler. Therefore + * the session gains exclusive access to the resources it requested, but only to deconfigure + * those of them that are not granted anymore. After this function is called, the session + * is responsible for releasing exclusive access to the requested resources by calling + * @ref nrf_802154_sl_rsch_ts_release. Failing to do so in the specified time margin might result + * in blocking other 802.15.4 operations as well as other radio protocols. + */ +typedef void (* nrf_802154_sl_rsch_ts_cleanup_callback_t)( + void * p_context, nrf_802154_sl_rsch_ts_cleanup_callback_metadata_t * p_metadata); + +/** @brief Structure that represents the parameters of a timeslot. */ +typedef struct +{ + /** @brief Resources necessary for the operations inside the timeslot to be successful. + */ + nrf_802154_sl_rsch_resource_t rsrc; + + /** @brief Type of the operation to be performed inside the timeslot. + */ + nrf_802154_sl_rsch_operation_t op; + + /** @brief Function called by the scheduler to indicate that timeslot has started. + */ + nrf_802154_sl_rsch_ts_start_callback_t start; + + /** @brief Function called by the scheduler to indicate that timeslot is about to end. + */ + nrf_802154_sl_rsch_ts_end_callback_t end; + + /** @brief Function called by the scheduler to indicate that timeslot was cancelled. + */ + nrf_802154_sl_rsch_ts_cancelled_callback_t cancelled; + + /** @brief Pointer to data provided by the caller that is unmodified by the scheduler + * and passed back to the caller in callbacks. + */ + void * p_context; + + /** @brief Flag that indicates if timeslot should be started immediately. + */ + bool immediate; + + /** @brief Absolute time in microseconds that the timeslot should start in. + * + * @note This field is used only if @p immediate is false. + */ + uint32_t target_time; + + /** @brief Requested time in microseconds that the timeslot is expected to last. + * + * If the timeslot's priority is set to the lowest priority possible, setting this field + * to 0 makes the timeslot last for an indefinite period of time. Such timeslot finished + * with a @ref nrf_802154_sl_rsch_ts_release call or when its end callback is called. + * + * @note If this field is set to 0 when the timeslot's priority is not the lowest possible, + * @ref nrf_802154_sl_rsch_ts_request returns @ref NRF_802154_SL_RSCH_RET_INVALID_PARAM + * and the timeslot is not scheduled. + */ + uint32_t duration_us; + + /** @brief Minimum time in microseconds that the timeslot can last to serve its purpose. + * + * If the caller wishes to allocate timeslot shorter than defined by @p duration_us + * that can be started earlier, this field should be set to a value indicating minimum + * duration of the timeslot that can be utilized by the caller. If the caller cannot + * utilize shorter timeslots than requested, this field shall be set to 0. + */ + uint32_t min_duration_us; + + /** @brief Minimum time in microseconds that a session needs to clean up after their timeslot. + * + * When a timeslot is about to be finished, @p end callback is issued to the session that + * requested it. This parameter specifies the minimum time that the session might need to + * perform all actions that need to be done before releasing the timeslot with + * @ref nrf_802154_sl_rsch_ts_release. + */ + uint32_t margin_us; + + /** @brief Priority of the timeslot. + * + * The lowest possible priority of a timeslot is equal @ref NRF_802154_SL_RSCH_TS_PRIORITY_LOWEST. + * Any number larger than that value indicates a higher priority. + */ + uint8_t priority; + +} nrf_802154_sl_rsch_ts_param_t; + +/** @brief Structure that represents timeslot parameters that can be updated. */ +typedef struct +{ + /** @brief Resources necessary for the operations inside the timeslot to be successful. + */ + nrf_802154_sl_rsch_resource_t rsrc; + + /** @brief Type of the operation to be performed inside the timeslot. + */ + nrf_802154_sl_rsch_operation_t op; + + /** @brief Requested time in microseconds that the timeslot is expected to last. + */ + uint32_t duration_us; + + /** @brief Priority of the timeslot. + * + * The lowest possible priority of a timeslot is equal @ref NRF_802154_SL_RSCH_TS_PRIORITY_LOWEST. + * Any number larger than that value indicates a higher priority. + */ + uint8_t priority; + +} nrf_802154_sl_rsch_ts_update_param_t; + +/** @brief Initializes the scheduler. + * + * @note This function must be called once, before any other function from this module. + * + * @note No timeslots are requested after initialization. In order to start radio activity, + * @ref nrf_802154_sl_rsch_ts_request should be called. + */ +void nrf_802154_sl_rsch_init(void); + +/** @brief Deinitializes the scheduler. */ +void nrf_802154_sl_rsch_deinit(void); + +/** @brief Initializes a session. + * + * @param[out] p_session Pointer to a session structure. + * + * @retval NRF_802154_SL_RSCH_RET_SUCCESS Session was initialized successfully. + * @retval NRF_802154_SL_RSCH_RET_ALREADY_REQUESTED Initialization failed. Session was initialized already. + * @retval NRF_802154_SL_RSCH_NO_MEMORY Initialization failed. The amount of available memory + * is insufficient. + */ +nrf_802154_sl_rsch_ret_t nrf_802154_sl_rsch_session_init(nrf_802154_sl_rsch_session_t * p_session); + +/** @brief Requests a timeslot. + * + * @note There can only be a single scheduled timeslot in a given session. + * + * When a timeslot is requested successfully and this function returns + * @ref NRF_802154_SL_RSCH_RET_SUCCESS, the scheduler assigns it a unique (within the provided + * session) identifier passed to the caller through @p p_ts_id. This identifier must be used + * in order to update parameters of a timeslot with @ref nrf_802154_sl_rsch_ts_param_update + * or release it by calling @ref nrf_802154_sl_rsch_ts_release. The identifier is also passed + * as a parameter of all callbacks registered by the caller upon request. + * + * @param[inout] p_session Pointer to the session that the timeslot belongs to. + * @param[in] p_param Pointer to structure that holds parameters defining the timeslot. + * @param[out] p_ts_id Pointer to the timeslot's identifier within a session. + * + * @retval NRF_802154_SL_RSCH_RET_SUCCESS Timeslot was requested successfully. + * @retval NRF_802154_SL_RSCH_RET_ALREADY_REQUESTED The specified session already has a timeslot + * request pending. + * @retval NRF_802154_SL_RSCH_RET_INVALID_PARAM The provided parameters are invalid. + * @retval NRF_802154_SL_RSCH_RET_HIGHER_PRIO There's a higher priority timeslot scheduled + * for an overlapping period of time. + */ +nrf_802154_sl_rsch_ret_t nrf_802154_sl_rsch_ts_request( + nrf_802154_sl_rsch_session_t * p_session, + const nrf_802154_sl_rsch_ts_param_t * p_param, + uint32_t * p_ts_id); + +/** @brief Releases a timeslot. + * + * Calling this function on behalf of a successfully requested but not yet started timeslot + * cancels that request. After calling this function the timeslot is not scheduled and is not + * going to start. + * + * Calling this function on behalf of an active (successfully requested and started) or ending + * (i.e. after end callback was issued) timeslot ends that timeslot. Its resources are released + * and can be used immediately by other sessions. + * + * @note The caller of this API is assumed to act cooperatively. Failing to release a timeslot + * in the specified time margin after receiving its end callback might lead to blocking other + * 802.15.4 operations as well as other radio protocols. + * + * @param[inout] p_session Pointer to the session that the timeslot belongs to. + * @param[in] ts_id Identifier of the timeslot to be released. + * + * @retval NRF_802154_SL_RSCH_RET_SUCCESS The timeslot was released successfully. + * @retval NRF_802154_SL_RSCH_RET_TIMESLOT_INACTIVE The timeslot could not be released because + * it has already been released or it was not + * requested at all. + */ +nrf_802154_sl_rsch_ret_t nrf_802154_sl_rsch_ts_release(nrf_802154_sl_rsch_session_t * p_session, + uint32_t ts_id); + +/** @brief Updates parameters of an active timeslot. + * + * This function can be called only to modify parameters of a currently active timeslot, + * i.e. a timeslot that started and was not yet released. Only a limited subset of all timeslot + * parameters can be modified when it is already active: its required resources, operation to be + * performed inside of it, its duration and priority. + * + * If there is another active timeslot running in parallel, which is using a separate subset + * of resources, and the resources passed in this function overlap with that separate subset, + * the scheduler chooses timeslots based on priority. If the updated priority is higher than + * the already running parallel timeslot, that timeslot is preempted with an end callback and its + * resources can be granted to the higher priority updated timeslot. If the priorities are equal, + * the already running timeslot is preferred and the update fails. If the updated priority is + * lower than the already running timeslot, the update fails. + * + * @note The caller of this API is assumed to act cooperatively. Repeatably extending timeslot's + * duration and increasing its priority might lead to blocking other 802.15.4 operations as well as + * other radio protocols. + * + * @note If the update is successful, the scheduler notifies the caller about the required resources + * being granted with a start callback. + * + * @note If the update fails, the original timeslot is not ended and its parameters still hold. + * + * @note If the update is not carried out before the timeslot ends, the session receives + * an end callback and it shall release the timeslot immediately. + * + * @note Irrespectively of whether the update is successful, the timeslot's identifier is not modified. + * + * @param[in] p_session Pointer to the session that the timeslot belongs to. + * @param[in] p_param Pointer to structure that holds timeslot parameters that can be updated. + * @param[in] ts_id Identifier of the timeslot to be updated. + * + * @retval NRF_802154_SL_RSCH_RET_SUCCESS Timeslot's parameters were updated successfully. + * @retval NRF_802154_SL_RSCH_RET_HIGHER_PRIO The update failed because the updated priority + * was not high enough to perform it. + * @retval NRF_802154_SL_RSCH_RET_TIMESLOT_INACTIVE The update failed because the timeslot is inactive. + */ +nrf_802154_sl_rsch_ret_t nrf_802154_sl_rsch_ts_param_update( + const nrf_802154_sl_rsch_session_t * p_session, + const nrf_802154_sl_rsch_ts_update_param_t * p_update_param); + +/** @brief Initializes timeslot request parameters to default values. + * + * @param[out] p_param Pointer to structure that holds timeslot parameters to be set to default. + */ +static inline void nrf_802154_sl_rsch_ts_param_init(nrf_802154_sl_rsch_ts_param_t * p_param) +{ + p_param->rsrc = NRF_802154_SL_RSCH_RSRC_NONE; + p_param->op = NRF_802154_SL_RSCH_OP_NONE; + p_param->start = NULL; + p_param->end = NULL; + p_param->cancelled = NULL; + p_param->p_context = NULL; + p_param->immediate = true; + p_param->target_time = 0; + p_param->duration_us = 0; + p_param->min_duration_us = 0; + p_param->margin_us = NRF_802154_SL_RSCH_DEFAULT_MARGIN_US; + p_param->priority = NRF_802154_SL_RSCH_TS_PRIORITY_LOWEST + 1; +} + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_802154_SL_RSCH_H__ diff --git a/nrf_802154_sl/include/nrf_802154_sl_stats.h b/nrf_802154_sl/include/nrf_802154_sl_stats.h new file mode 100644 index 0000000..63a43a1 --- /dev/null +++ b/nrf_802154_sl/include/nrf_802154_sl_stats.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_802154_SL_STATS_H__ +#define NRF_802154_SL_STATS_H__ + +#define nrf_802154_sl_stat_counter_increment(...) + +#endif // NRF_802154_SL_STATS_H__ diff --git a/nrf_802154_sl/include/nrf_802154_sl_timer.h b/nrf_802154_sl/include/nrf_802154_sl_timer.h new file mode 100644 index 0000000..b5ce32d --- /dev/null +++ b/nrf_802154_sl/include/nrf_802154_sl_timer.h @@ -0,0 +1,489 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Module that provides the timer service for the 802.15.4 driver. + * + * There are two main features of this module. + * - @b timer allowing scheduling further action to happen. Object of type + * @ref nrf_802154_sl_timer_t (and related functions) is responsible for this feature. + * + * - @b timestamper allowing timestamping of hardware events occuring in peripherals. + * Object of type @ref nrf_802154_sl_timestamper_t (and related functions) is + * responsible for this feature. + * + * There are two time resolutions available: + * - @b coarse with resolution of 1/32768 s + * - @b fine with resolution of 1 microsecond. + * + * Fine resolution time service requires a hardware fine resolution timer to be started which can + * increase power consumption. The fine resolution timer is started on demand + * by timestampers or software fine resolution timers. The fine resolution timer is stopped + * when no timestmpers and no timers require fine resolution anymore. + * + * This module levarages concept of binding hardware events to hardware tasks. When event is + * bound to a task the event may trigger the task automaticaly by the hardware. To make + * such binding hardware PPI/DPPI channels, hardware EGU channels and/or hardware timer + * capture/compare channels may be used according to API defined by nrf_802154_sl_bet.h module. + * Binding is performed automatically by the implementation of timer module. + */ + +#ifndef NRF_802154_SL_TIMER_H_ +#define NRF_802154_SL_TIMER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_802154_sl_timer Timer Service + * @{ + * @ingroup nrf_802154_sl_timer + * @brief The Timer Service for the 802.15.4 driver. + * + */ + +/**@brief Number of words required by @ref nrf_802154_sl_timer_priv_placeholder_t. */ +#define NRF_802154_SL_TIMER_PRIV_SIZE 1U + +/**@brief Number of words required by @ref nrf_802154_sl_timestamper_priv_placeholder_t. */ +#define NRF_802154_SL_TIMESTAMPER_PRIV_SIZE 1U + +/**@brief Type of result returned by timer-related functions. + * + * Possible values: + * @ref NRF_802154_SL_TIMER_RET_SUCCESS + * @ref NRF_802154_SL_TIMER_RET_TOO_LATE + * @ref NRF_802154_SL_TIMER_RET_ACTION_IN_PROGRESS + * @ref NRF_802154_SL_TIMER_RET_NO_RESOURCES + * @ref NRF_802154_SL_TIMER_RET_BAD_STATE + */ +typedef uint32_t nrf_802154_sl_timer_ret_t; + +/**@brief Operation performed successfully. */ +#define NRF_802154_SL_TIMER_RET_SUCCESS 0U + +/**@brief Operation was requested too late to be scheduled in requested time. */ +#define NRF_802154_SL_TIMER_RET_TOO_LATE 1U + +/**@brief Operation was requested when there was no way to prevent previously scheduled activity. */ +#define NRF_802154_SL_TIMER_RET_ACTION_IN_PROGRESS 2U + +/**@brief There were no available resources required to schedule requested activity. + * + * This result may happen for @ref nrf_802154_sl_timer_add with + * @ref nrf_802154_sl_timer_t::action_type equal to + * @ref NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE_TASK. To trigger hardware task by the timer, + * some hardware resources like PPI/DPPI channels, EGU channels, timer compare channels + * (implementation dependent) were needed, but they were unavailable. + */ +#define NRF_802154_SL_TIMER_RET_NO_RESOURCES 3U + +/**@brief The state of a timer object was inappropriate for requested operation. */ +#define NRF_802154_SL_TIMER_RET_BAD_STATE 4U + +/**@brief Type representing timer. */ +typedef struct nrf_802154_sl_timer_s nrf_802154_sl_timer_t; + +/**@brief Type of callback function pointer to be called when timer triggers. */ +typedef void (* nrf_802154_sl_timer_callback_t)(nrf_802154_sl_timer_t * p_timer); + +/**@brief Action types to be perfromed when a timer triggers. + * + * Possible values: + * @ref NRF_802154_SL_TIMER_ACTION_TYPE_CALLBACK + * @ref NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE_TASK + */ +typedef uint8_t nrf_802154_sl_timer_action_type_t; + +/**@brief Timer action type causing a callback to be called. */ +#define NRF_802154_SL_TIMER_ACTION_TYPE_CALLBACK 0U +/**@brief Timer action type causing a hardware task to be triggered. */ +#define NRF_802154_SL_TIMER_ACTION_TYPE_HARDWARE_TASK 1U + +/**@brief Structure that represents private fields of a timer required by the implementation. */ +typedef struct +{ + uint32_t placeholder[NRF_802154_SL_TIMER_PRIV_SIZE]; +} nrf_802154_sl_timer_priv_placeholder_t; + +struct nrf_802154_sl_timer_s +{ + /**@brief Private fields required by the implementation. */ + nrf_802154_sl_timer_priv_placeholder_t priv; + + /**@brief The timestamp in microseconds at which the timer should be triggered. + * + * For action_type == nrf_802154_sl_timer_action_type_callback the timer + * resolution is always nrf_802154_sl_timer_resolution_coarse. The callback will + * be called no earlier than at given @p trigger_time, but may be delayed due + * to processing time taken by other ISRs. + */ + uint32_t trigger_time; + + /**@brief User-provided data. + * + * User preparing a timer can store any data within this field. Timer module does not + * process this data. + */ + void * p_user_data; + + /**@brief Action type to be performed when the timer triggers. + * + * Depending on value of this field, appropriate version of @c action union variant + * is valid. + */ + nrf_802154_sl_timer_action_type_t action_type; + + union + { + /**@brief Parameters applicable when @c action_type is equal to + * @ref NRF_802154_SL_TIMER_ACTION_TYPE_CALLBACK */ + struct + { + /**@brief Callback to be called when the timer triggers. + * + * The callback is called within an ISR. Please take into account possible + * latency between moment of trigger and moment when the callback gets called. + */ + nrf_802154_sl_timer_callback_t callback; + } callback; + + /**@brief Parameters applicable when @c action_type is equal to + * @ref NRF_802154_SL_TIMER_ACTION_HARDWARE_TASK */ + struct + { + /**@brief Address of a hardware task register of a peripheral to be triggered. */ + uint32_t task_addr; + } hardware_task; + } action; +}; + +/**@brief Initializes the timer module. */ +void nrf_802154_sl_timer_module_init(void); + +/**@brief Uninitializes the timer module. */ +void nrf_802154_sl_timer_module_uninit(void); + +/**@brief Gets current time. + * + * @return Time in microseconds with coarse resolution. + */ +uint32_t nrf_802154_sl_timer_current_time_get(void); + +/**@brief Initializes a timer instance. + * + * This function plays a role of a constructor. It should be called once + * per timer instance before any other API call related to given + * timer instance. Calling any other API related to a timer + * instance before call to @ref nrf_802154_sl_timer_init or + * calling @ref nrf_802154_sl_timer_init more than once is an + * undefined behavior. + * + * @param p_timer Pointer to a timer instance to be initialized. + */ +void nrf_802154_sl_timer_init(nrf_802154_sl_timer_t * p_timer); + +/**@brief Adds a timer to the active timers list. + * + * This function adds the timer pointed by @p p_timer parameter to an active timers + * list. Before call to @ref nrf_802154_sl_timer_add the timer must fill + * public fields of timer object instance in the following way: + * - @ref nrf_802154_sl_timer_t::trigger_time is set up to the moment when the timer + * is expected to trigger + * - Optionally @ref nrf_802154_sl_timer_t::p_user_data may be set, to user-dependent value. + * - @ref nrf_802154_sl_timer_t::action_type is set according to requested action. + * - Depending on value written to @ref nrf_802154_sl_timer_t::action_type + * matching version on union @ref nrf_802154_sl_timer_t::action must be filled. + * + * When this function succeeds the timer module takes ownership of the timer instance. + * A user is forbidden to modify structure until callback or @ref nrf_802154_sl_timer_remove + * is called. + * + * @param p_timer Pointer to a timer instance to add to active timers list. + * + * @retval NRF_802154_SL_TIMER_RET_SUCCESS + * Function succeeded. The timer is sussessfully added. The requested action is + * scheduled to happen. + * @retval NRF_802154_SL_TIMER_RET_TOO_LATE + * The requested trigger_time is too close in the future or is already in the past. + * @retval NRF_802154_SL_TIMER_RET_NO_RESOURCES + * The requested task can't be bound to the timer due to lack of hardware resources. + * @retval NRF_802154_SL_TIMER_RET_BAD_STATE + * A user requested to add a timer actually owned by the timers service. + */ +nrf_802154_sl_timer_ret_t nrf_802154_sl_timer_add(nrf_802154_sl_timer_t * p_timer); + +/**@brief Removes a timer from the active timers list. + * + * @param p_timer Pointer to a timer instance to be removed from the active timers list. + * + * @retval NRF_802154_SL_TIMER_RET_SUCCESS + * The timer was running and it has been successfully removed from active timers list. + * The requested action (either callback or hardware task trigger) will not happen. + * When requested action was to trigger hardware task, any hardware bindings between + * timer module and requested task is removed. + * @retval NRF_802154_SL_TIMER_RET_TOO_LATE + * The timer was already not running at the moment of call. The request action is finished. + * When callback was requested it means that the callback has been called and its execution + * finished. The timer is removed from the active timers queue. + * When requested action was to trigger hardware task, the task has been triggered. + * The timer is removed from the active timers queue, any hardware bindings between timer + * module and requested task is removed. + * @retval NRF_802154_SL_TIMER_RET_ACTION_IN_PROGRESS + * The timer was not running but it's requested action has not finished yet. + * When callback was requested it means that the timer triggered callback execution, + * but the calback has not finished yet its execution. This may happen when the timer + * is removed from an ISR of higher priority than ISR performing timer callback execution. + * The implementation of user provided callback determines if it is safe to reuse the timer. + * When requested action was to trigger hardware task, this result will not be returned. + */ +nrf_802154_sl_timer_ret_t nrf_802154_sl_timer_remove(nrf_802154_sl_timer_t * p_timer); + +/**@brief Type representing a timestamper object. */ +typedef struct nrf_802154_sl_timestamper_s nrf_802154_sl_timestamper_t; + +/**@brief Structure that represents private fields of a timestamper required + * by the implementation. */ +typedef struct +{ + uint32_t placeholder[NRF_802154_SL_TIMESTAMPER_PRIV_SIZE]; +} nrf_802154_sl_timestamper_priv_placeholder_t; + +struct nrf_802154_sl_timestamper_s +{ + /**@brief Private fields required by the implementation. */ + nrf_802154_sl_timestamper_priv_placeholder_t priv; +}; + +/**@brief Type of result returned by timer-related functions. + * + * Possible values: + * @ref NRF_802154_SL_TIMESTAMPER_RET_SUCCESS, + * @ref NRF_802154_SL_TIMESTAMPER_RET_NO_RESOURCES, + * @ref NRF_802154_SL_TIMESTAMPER_RET_BAD_STATE, + * @ref NRF_802154_SL_TIMESTAMPER_RET_NO_EVENT, + * @ref NRF_802154_SL_TIMESTAMPER_RET_TRY_LATER. + */ +typedef uint32_t nrf_802154_sl_timestamper_ret_t; + +/**@brief Operation on a timestamper succeed. */ +#define NRF_802154_SL_TIMESTAMPER_RET_SUCCESS 0U + +/**@brief Operation on a timestamper failed due to lack of required resources. + * + * Timestamper may require hardware compare channels of fine resolution timer, + * hardware PPI/DPPI channels, possibly hardware EGU channels (implementation defined) + * to bind given event to timer's capture task. This result indicates that some of these + * resources were unavailable. + */ +#define NRF_802154_SL_TIMESTAMPER_RET_NO_RESOURCES 1U + +/**@brief The state of a timestamper object was inappropriate for requested operation. */ +#define NRF_802154_SL_TIMESTAMPER_RET_BAD_STATE 2U + +/**@brief Event which should be timestamped has not triggered yet. */ +#define NRF_802154_SL_TIMESTAMPER_RET_NO_EVENT 3U + +/**@brief Calculation of timestamp is impossible due to not synchronized fine and coarse + * resolution timers. + * + * Please refer to @ref nrf_802154_sl_timestamper_timestamp_get for details. + */ +#define NRF_802154_SL_TIMESTAMPER_RET_TRY_LATER 4U + +/**@brief Initializes an instance of a timestamper object. + * + * This function plays a role of a constructor. It should be called once + * per timestamper instance before any other API call related to given + * timestamper instance. Calling any other API related to a timestamper + * instance before call to @ref nrf_802154_sl_timestamper_init or + * calling @ref nrf_802154_sl_timestamper_init more than once is an + * undefined behavior. + * + * @param p_timestamper Pointer to a timestamper object instance to be initialized. + */ +void nrf_802154_sl_timestamper_init(nrf_802154_sl_timestamper_t * p_timestamper); + +/**@brief Prepares timestamper instance to allow timestamping of an hardware event. + * + * Timestamper can make a single timestamp of a hardware event. + * In case of successful execution this functions causes: + * - creation of hardware bindings between given event and fine resolution timer + * - start of fine resolution timer if not running yet. + * + * When the hardware event triggerring timestamp is made. The timer module + * does not provide any way of triggering software action in response to an event. + * Providing such feature, i.e. appropriate ISR for given event, is a responsibilty + * of a user. The user should call either @ref nrf_802154_sl_timestamper_fetch + * or @ref nrf_802154_sl_timestamper_timestamp_get as early after event occurrence as + * practically possible to release hardware resources used for timestamping. + * + * When the user is done with the timestamper @ref nrf_802154_sl_timestamper_cleanup + * should be called. When the user wishes to re-use the timestamper instance, + * @ref @ref nrf_802154_sl_timestamper_cleanup should be called first and then + * @ref nrf_802154_sl_timestamper_setup should be called. + * + * @param p_timestamper Pointer to a timestamper object that is responsible for + * keeping timestamper state. + * @param event_addr Address of a hardware event register of a peripheral which will be + * timestamped by given timestamper instance. When 0 is provided + * the current moment of call will be timestamped (possibly imprecise). + * In this case no hardware bindings are made, but fine resolution + * timer will be requested (if not running yet). + * + * @retval NRF_802154_SL_TIMESTAMPER_RET_SUCCESS + * The timestamper setup was successful. + * + * @retval NRF_802154_SL_TIMESTAMPER_RET_NO_RESOURCES + * There was no hardware resources to perform timestamping. + * + * @retval NRF_802154_SL_TIMESTAMPER_RET_BAD_STATE + * The timestamper was already setup to perform timestamping and no cleanup + * has been called yet. + */ +nrf_802154_sl_timestamper_ret_t nrf_802154_sl_timestamper_setup( + nrf_802154_sl_timestamper_t * p_timestamper, + uint32_t event_addr); + +/**@brief Fetches data required to calculate timestamp. + * + * This function fetches data allowing calculation of absolute timestamp by further call to + * @ref nrf_802154_sl_timestamper_timestamp_get. When it succeeds, some resources required for + * timestamping (compare channels, hardware event bindings) are released and can be + * re-used. + * + * When fine resolution timer is synchronized to coarse resolution timer, all data + * allowing successfull @ref nrf_802154_sl_timestamper_timestamp_get is stored within + * timestamper object. + * + * When fine resolution timer is not synchronized yet to coarse resolution timer, + * almost all data is stored within timestamper object and remaining data will be stored + * in timestamper object by synchronization event. + * + * Call to this function does not stop fine resolution timer as this can be done by + * @ref nrf_802154_sl_timestamper_cleanup only. + * + * @retval NRF_802154_SL_TIMESTAMPER_RET_SUCCESS + * The event being timestamped has triggered. The data required to calculate timestamp + * has been latched within the timestamper object. The hardware bindings between event and + * timer have been cleaned up as they have become not necessary. + * + * @retval NRF_802154_SL_TIMESTAMPER_RET_BAD_STATE + * The timestamper has not been setup for timestamping (@ref nrf_802154_sl_timestamper_setup + * has not been called before). The timestamper state remains unchanged. + * + * @retval NRF_802154_SL_TIMESTAMPER_RET_NO_EVENT + * The event being timestamped has not triggered yet. The timestamper state remains + * unchanged. + */ +nrf_802154_sl_timestamper_ret_t nrf_802154_sl_timestamper_fetch( + nrf_802154_sl_timestamper_t * p_timestamper); + +/**@brief Gets timestamp made by a timestamper. + * + * This function calls internally @ref nrf_802154_sl_timestamper_fetch when necessary. + * After that when all data is stored within timestamper object it calculates + * timestamp. + * + * Call to this function does not stop fine resolution timer as this can be done by + * @ref nrf_802154_sl_timestamper_cleanup only. + * + * The timestamper object can be re-used by call to @ref nrf_802154_sl_timestamper_cleanup + * and then @ref nrf_802154_sl_timestamper_setup. + * + * @param p_timestamper Pointer to a timestamper instance. + * @param p_timestamp Timestamp in microseconds of an event will be written + * at this pointer if the function returns + * @ref NRF_802154_SL_TIMESTAMPER_RET_SUCCESS. + * + * @retval NRF_802154_SL_TIMESTAMPER_RET_SUCCESS + * The timestamp is available and written at p_timestamp pointer. + * + * @retval NRF_802154_SL_TIMESTAMPER_RET_BAD_STATE + * The timestamper has not been setup for timestamping, i.e. + * @ref nrf_802154_sl_timestamper_setup has not been called before. + * + * @retval NRF_802154_SL_TIMESTAMPER_RET_NO_EVENT + * The event being timestamped has not triggered yet. + * + * @retval NRF_802154_SL_TIMESTAMPER_RET_TRY_LATER + * The event has triggered and the data allowing timestamping is fetched, but + * currently this data doesn't allow calculation of absolute timestamp. + * The timestamp will be available later when coarse and fine clocks are synchronized. + */ +nrf_802154_sl_timestamper_ret_t nrf_802154_sl_timestamper_timestamp_get( + nrf_802154_sl_timestamper_t * p_timestamper, + uint32_t * p_timestamp); + +/**@brief Cleans up after timestamping. + * + * This function definitely ends timestamping process related to given timestamper instance. + * This function must be called complementary to @ref nrf_802154_sl_timestamper_setup + * no matter if user managed to get the timestamp or not. + * + * This function is responsible for cleaning up after @ref nrf_802154_sl_timestamper_setup. + * It removes any hardware bindings (if still existing) made + * by @ref nrf_802154_sl_timestamper_setup, frees any resources allocated by the call and + * releases fine resolution timer (if still requested). Please note that fine resolution timer + * can be left running if other resources require it (other timestampers, timers etc.). + * + * When the user calls this function on a timestamper instance which has not been setup + * for timestamping, i.e. @ref nrf_802154_sl_timestamper_setup has not been called, + * the call does nothing. + * + * If user didn't call @ref nrf_802154_sl_timestamper_timestamp_get the timestamp + * (if it has been ever made) will be lost, but it allows abandoning of timestamping + * and releases used resources. + * + * @param p_timestamper Pointer to a timestamper instance to be cleaned up. + */ +void nrf_802154_sl_timestamper_cleanup(nrf_802154_sl_timestamper_t * p_timestamper); + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_802154_SL_TIMER_H_ */ diff --git a/nrf_802154_sl/include/nrf_802154_sl_utils.h b/nrf_802154_sl/include/nrf_802154_sl_utils.h new file mode 100644 index 0000000..1d86d54 --- /dev/null +++ b/nrf_802154_sl/include/nrf_802154_sl_utils.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file Definitions of utils used in the nRF 802.15.4 Service Layer. + * + */ + +#ifndef NRF_802154_SL_UTILS_H__ +#define NRF_802154_SL_UTILS_H__ + +#include +#include "nrf.h" + +/**@brief RTC clock frequency. */ +#define NRF_802154_SL_RTC_FREQUENCY 32768UL + +/**@brief Defines the number of microseconds in one second. */ +#define NRF_802154_SL_US_PER_S 1000000ULL + +/**@brief Number of microseconds in one RTC tick (rounded up). */ +#define NRF_802154_SL_US_PER_TICK NRF_802154_SL_RTC_TICKS_TO_US(1) + +/**@brief Number of bits to shift RTC_FREQUENCY and US_PER_S to achieve the division by greatest common divisor. */ +#define NRF_802154_SL_FREQUENCY_US_PER_S_GCD_BITS 6 + +/**@brief Ceil division helper. */ +#define NRF_802154_SL_DIVIDE_AND_CEIL(A, B) (((A) + (B)-1) / (B)) + +/**@brief Defines the conversion of RTC ticks to microseconds (us). */ +#define NRF_802154_SL_RTC_TICKS_TO_US(ticks) \ + NRF_802154_SL_DIVIDE_AND_CEIL( \ + (ticks) * (NRF_802154_SL_US_PER_S >> NRF_802154_SL_FREQUENCY_US_PER_S_GCD_BITS), \ + (NRF_802154_SL_RTC_FREQUENCY >> NRF_802154_SL_FREQUENCY_US_PER_S_GCD_BITS)) + +/**@brief Converts microseconds (us) to RTC ticks. */ +uint64_t NRF_802154_SL_US_TO_RTC_TICKS(uint64_t time); + +/**@brief Type holding MCU critical section state. + * + * Variable of this type is required to hold state saved by @ref nrf_802154_sl_mcu_critical_enter + * and restored by @ref nrf_802154_sl_mcu_critical_exit. + */ +typedef uint32_t nrf_802154_sl_mcu_critical_state_t; + +/**@brief Enters critical section on MCU level. + * + * Use @ref nrf_802154_sl_mcu_critical_exit complementary. Consider following code: + * @code + * nrf_802154_sl_mcu_critical_state_t mcu_cs; + * nrf_802154_sl_mcu_critical_enter(mcu_cs); + * // do your critical stuff as fast as possible + * nrf_802154_sl_mcu_critical_exit(mcu_cs); + * @endcode + * + * @param mcu_critical_state Variable of @ref nrf_802154_sl_mcu_critical_state_t where current + * state of MCU level critical section will be stored. + */ +#define nrf_802154_sl_mcu_critical_enter(mcu_critical_state) \ + do \ + { \ + (mcu_critical_state) = __get_PRIMASK(); \ + __disable_irq(); \ + } \ + while (0) + +/**@brief Exits critical section on MCU level. + * + * This shall be used complementary to @ref nrf_802154_sl_mcu_critical_enter. + * + * @param mcu_critical_state Variable of @ref nrf_802154_sl_mcu_critical_state_t where + * state of MCU level critical section is stored by + * former call to @ref nrf_802154_sl_mcu_critical_enter + */ +#define nrf_802154_sl_mcu_critical_exit(mcu_critical_state) \ + do \ + { \ + __set_PRIMASK(mcu_critical_state); \ + } \ + while (0) + +#endif // NRF_802154_SL_UTILS_H__ diff --git a/src/platform/clock/nrf_802154_clock.h b/nrf_802154_sl/include/platform/clock/nrf_802154_clock.h similarity index 57% rename from src/platform/clock/nrf_802154_clock.h rename to nrf_802154_sl/include/platform/clock/nrf_802154_clock.h index 595c549..9ba8d6c 100644 --- a/src/platform/clock/nrf_802154_clock.h +++ b/nrf_802154_sl/include/platform/clock/nrf_802154_clock.h @@ -1,31 +1,39 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/nrf_802154_sl/include/platform/gpiote/nrf_802154_gpiote.h b/nrf_802154_sl/include/platform/gpiote/nrf_802154_gpiote.h new file mode 100644 index 0000000..acceef6 --- /dev/null +++ b/nrf_802154_sl/include/platform/gpiote/nrf_802154_gpiote.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Module that defines API of GPIOTE for the 802.15.4 driver. + * + */ + +#ifndef NRF_802154_GPIOTE_H_ +#define NRF_802154_GPIOTE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_802154_gpiote GPIOTE for the 802.15.4 driver + * @{ + * @ingroup nrf_802154_gpiote + * @brief GPIOTE for the 802.15.4 driver. + * + * The GPIOTE is used to react on the Coex Grant line. + * + */ + +/** + * @brief Initializes the GPIOTE. + */ +void nrf_802154_gpiote_init(void); + +/** + * @brief Deinitializes the GPIOTE. + */ +void nrf_802154_gpiote_deinit(void); + +/** + * @brief Function to be called when handling the pin triggering. + */ +extern void nrf_802154_wifi_coex_gpiote_irqhandler(void); + +/** + * @brief Enter the critical section of GPIOTE subsystem. + * + * @note The critical section can be nested. + * + */ +void nrf_802154_gpiote_critical_section_enter(void); + +/** + * @brief Exit the critical section of GPIOTE subsystem. + * + * @note The critical section can be nested. + * + */ +void nrf_802154_gpiote_critical_section_exit(void); + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_802154_GPIOTE_H_ */ diff --git a/src/platform/hp_timer/nrf_802154_hp_timer.h b/nrf_802154_sl/include/platform/hp_timer/nrf_802154_hp_timer.h similarity index 61% rename from src/platform/hp_timer/nrf_802154_hp_timer.h rename to nrf_802154_sl/include/platform/hp_timer/nrf_802154_hp_timer.h index b36abc8..9117ee5 100644 --- a/src/platform/hp_timer/nrf_802154_hp_timer.h +++ b/nrf_802154_sl/include/platform/hp_timer/nrf_802154_hp_timer.h @@ -1,31 +1,39 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/platform/irq/nrf_802154_irq.h b/nrf_802154_sl/include/platform/irq/nrf_802154_irq.h similarity index 100% rename from src/platform/irq/nrf_802154_irq.h rename to nrf_802154_sl/include/platform/irq/nrf_802154_irq.h diff --git a/src/platform/lp_timer/nrf_802154_lp_timer.h b/nrf_802154_sl/include/platform/lp_timer/nrf_802154_lp_timer.h similarity index 75% rename from src/platform/lp_timer/nrf_802154_lp_timer.h rename to nrf_802154_sl/include/platform/lp_timer/nrf_802154_lp_timer.h index 19d4a4c..085909a 100644 --- a/src/platform/lp_timer/nrf_802154_lp_timer.h +++ b/nrf_802154_sl/include/platform/lp_timer/nrf_802154_lp_timer.h @@ -1,31 +1,39 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/nrf_802154_sl/include/rsch/coex/nrf_802154_wifi_coex.h b/nrf_802154_sl/include/rsch/coex/nrf_802154_wifi_coex.h new file mode 100644 index 0000000..54e7ee7 --- /dev/null +++ b/nrf_802154_sl/include/rsch/coex/nrf_802154_wifi_coex.h @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Module that defines the Wi-Fi coexistence module. + * + */ + +#ifndef NRF_802154_WIFI_COEX_H_ +#define NRF_802154_WIFI_COEX_H_ + +#include + +#include "nrf_802154_sl_config.h" +#include "rsch/nrf_802154_rsch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_wifi_coex Wi-Fi Coexistence + * @{ + * @ingroup nrf_802154 + * @brief The Wi-Fi Coexistence module. + * + * The Wi-Fi Coexistence module is a client of the PTA (defined in the 802.15.2). It manages GPIO + * to assert pins and respond to pin state changes. + */ + +/**@brief Enumeration representing state of request to PTA */ +typedef enum +{ + /** @brief No request is being made to PTA. */ + WIFI_COEX_REQUEST_STATE_NO_REQUEST = 0, + /** @brief Requesting receive mode to PTA. */ + WIFI_COEX_REQUEST_STATE_RX, + /** @brief Requesting transmit mode to PTA. */ + WIFI_COEX_REQUEST_STATE_TX +} nrf_802154_wifi_coex_request_state_t; + +/** + * @brief Deinitializes the Wi-Fi Coexistence module. + * + */ +void nrf_802154_wifi_coex_uninit(void); + +/** + * @brief Requests the given priority from the Wi-Fi Coexistence module. + * + * @note The approval of the requested priority is notified asynchronously by the + * @ref nrf_802154_wifi_coex_prio_changed call. + * + * @param[in] priority The requested priority level. + * + */ +void nrf_802154_wifi_coex_prio_request(rsch_prio_t priority); + +/** + * @brief Gets the priority denial event address. + * + * Get the address of a hardware event that notifies about the denial of a previously approved + * priority. + * + * @returns Address of the priority denial event. + */ +void * nrf_802154_wifi_coex_deny_event_addr_get(void); + +/** + * @brief Notifies about the approved priority change. + * + * The Wi-Fi Coexistence module calls this function to notify the RSCH of the currently approved + * priority level. + * + * @param[in] priority The approved priority level. + */ +extern void nrf_802154_wifi_coex_prio_changed(rsch_prio_t priority); + +/** + * @brief Notifies about any change of request signaled to PTA. + * + * This function may be called from an ISR in consequence of call to @ref nrf_802154_wifi_coex_prio_request + * or from inside of the @ref nrf_802154_wifi_coex_prio_request function. + * This function is called on changes of request signal only. After @ref nrf_802154_wifi_coex_init + * no request is signaled to PTA so @ref WIFI_COEX_REQUEST_STATE_NO_REQUEST value is assumed as + * request_state value. @ref nrf_802154_wifi_coex_init does not call the + * @ref nrf_802154_wifi_coex_request_changed. + * + * @param[in] curr_request_state Current request signaled to PTA. + * @param[in] prev_request_state Previous request signaled to PTA. + * @param[in] grant_state State of grant signal just before change to request signal was made. + */ +extern void nrf_802154_wifi_coex_request_changed( + nrf_802154_wifi_coex_request_state_t curr_request_state, + nrf_802154_wifi_coex_request_state_t prev_request_state, + bool grant_state); + +/** + * @brief Notifies that access to the medium was granted by the PTA. + * + * @param[in] curr_request_state Current request signaled to PTA. + */ +extern void nrf_802154_wifi_coex_granted(nrf_802154_wifi_coex_request_state_t curr_request_state); + +/** + * @brief Notifies that access to the medium was denied by the PTA. + * + * @param[in] curr_request_state Current request signaled to PTA. + */ +extern void nrf_802154_wifi_coex_denied(nrf_802154_wifi_coex_request_state_t curr_request_state); + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_802154_WIFI_COEX_H_ */ diff --git a/src/rsch/nrf_802154_rsch.h b/nrf_802154_sl/include/rsch/nrf_802154_rsch.h similarity index 58% rename from src/rsch/nrf_802154_rsch.h rename to nrf_802154_sl/include/rsch/nrf_802154_rsch.h index 5d25857..b628a75 100644 --- a/src/rsch/nrf_802154_rsch.h +++ b/nrf_802154_sl/include/rsch/nrf_802154_rsch.h @@ -1,31 +1,39 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @@ -90,10 +98,49 @@ typedef enum { RSCH_DLY_TX, ///< Timeslot for delayed TX operation. RSCH_DLY_RX, ///< Timeslot for delayed RX operation. + RSCH_DLY_CSMACA, ///< Timeslot for CSMA/CA operation. RSCH_DLY_TS_NUM, ///< Number of delayed timeslots. } rsch_dly_ts_id_t; +/** + * @brief Enumeration of the precondition requesting strategies. + */ +typedef enum +{ + /** The following delayed timeslot type requires preconditions to be requested immediately + * and released only by @ref nrf_802154_rsch_delayed_timeslot_cancel call. It is scheduled + * irrespectively of current approved preconditions, which might introduce additional delays. + * This delayed timeslot type also supports requests with target time in the past. + */ + RSCH_DLY_TS_TYPE_RELAXED, + + /** The following delayed timeslot type requires preconditions to be requested as late + * as possible to ensure they are ramped up on target time, and released as soon as possible. + * This mode of operation does not allow for requests in the past and puts strict conditions + * on preconditions that must be approved when the scheduled operation starts. + */ + RSCH_DLY_TS_TYPE_PRECISE, +} rsch_dly_ts_type_t; + +/** + * @brief Function pointer used for notifying about delayed timeslot start. + */ +typedef void (* rsch_dly_ts_started_callback_t)(rsch_dly_ts_id_t dly_ts_id); + +/** + * @brief Structure that holds parameters of a delayed timeslot request. + */ +typedef struct +{ + uint32_t t0; ///< Base time of the timestamp of the timeslot start, in microseconds. + uint32_t dt; ///< Time delta between @p t0 and the timestamp of the timeslot start, in microseconds. + rsch_prio_t prio; ///< Priority level required for the delayed timeslot. + rsch_dly_ts_id_t id; ///< ID of the requested timeslot. + rsch_dly_ts_type_t type; ///< Type of the requested timeslot. + rsch_dly_ts_started_callback_t started_callback; ///< Callback called when delayed timeslot starts. +} rsch_dly_ts_param_t; + /** * @brief Initializes Radio Scheduler. * @@ -155,38 +202,42 @@ bool nrf_802154_rsch_timeslot_request(uint32_t length_us); * * Request timeslot that is to be granted in the future. The function parameters provide data when * the timeslot is supposed to start and how long it is to last. When the requested timeslot starts, - * @ref nrf_802154_rsch_delayed_timeslot_started is called. + * @p p_dly_ts_param->started_callback is called. * - * @note @ref nrf_802154_rsch_delayed_timeslot_started can be delayed and it is up to + * @note @p p_dly_ts_param->started_callback can be delayed and it is up to * the called module to check the delay and decide if it causes any issues. * * @note The time parameters use the same units that are used in the Timer Scheduler module. * - * @param[in] t0 Base time of the timestamp of the timeslot start, in microseconds. - * @param[in] dt Time delta between @p t0 and the timestamp of the timeslot start, in microseconds. - * @param[in] length Requested radio timeslot length, in microseconds. - * @param[in] prio Priority level required for the delayed timeslot. - * @param[in] dly_ts Type of the requested timeslot. + * @param[in] p_dly_ts_param Parameters of the requested delayed timeslot. * * @retval true Requested timeslot has been scheduled. * @retval false Requested timeslot cannot be scheduled and will not be granted. */ -bool nrf_802154_rsch_delayed_timeslot_request(uint32_t t0, - uint32_t dt, - uint32_t length, - rsch_prio_t prio, - rsch_dly_ts_id_t dly_ts); +bool nrf_802154_rsch_delayed_timeslot_request(const rsch_dly_ts_param_t * p_dly_ts_param); /** * @brief Cancels a requested future timeslot. * - * @param[in] dly_ts_id Type of the requested timeslot. + * @param[in] dly_ts_id ID of the requested timeslot. * * @retval true Scheduled timeslot has been cancelled. * @retval false No scheduled timeslot has been requested (nothing to cancel). */ bool nrf_802154_rsch_delayed_timeslot_cancel(rsch_dly_ts_id_t dly_ts_id); +/** + * @brief Updates priority of a requested delayed timeslot. + * + * @param[in] dly_ts_id ID of the requested timeslot. + * @param[in] dly_ts_prio Priority to be assigned to the requested timeslot. + * + * @retval true Scheduled timeslot's priority has been updated. + * @retval false Priority of the specified timeslot could not be updated. + */ +bool nrf_802154_rsch_delayed_timeslot_priority_update(rsch_dly_ts_id_t dly_ts_id, + rsch_prio_t dly_ts_prio); + /** * @brief Checks if there is a pending timeslot request. * @@ -228,13 +279,6 @@ uint32_t nrf_802154_rsch_timeslot_us_left_get(void); */ extern void nrf_802154_rsch_continuous_prio_changed(rsch_prio_t prio); -/** - * @brief Notifies that the previously requested delayed timeslot has started just now. - * - * @param[in] dly_ts_id Type of the started timeslot. - */ -extern void nrf_802154_rsch_delayed_timeslot_started(rsch_dly_ts_id_t dly_ts_id); - /** *@} **/ diff --git a/nrf_802154_sl/include/rsch/nrf_802154_rsch_crit_sect.h b/nrf_802154_sl/include/rsch/nrf_802154_rsch_crit_sect.h new file mode 100644 index 0000000..72010fe --- /dev/null +++ b/nrf_802154_sl/include/rsch/nrf_802154_rsch_crit_sect.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_802154_RSCH_CRIT_SECT_H__ +#define NRF_802154_RSCH_CRIT_SECT_H__ + +#include + +#include "rsch/nrf_802154_rsch.h" + +/** + * @defgroup nrf_802154_rsch_crit_sect RSCH event queue used during critical sections + * @{ + * @ingroup nrf_802154_rsch + * @brief The critical section implementation for the RSCH module. + */ + +/** + * @brief Pointer to function used to enter critical section. + */ +typedef bool (* nrf_802154_sl_crit_sect_enter_t)(void); + +/** + * @brief Pointer to function used to exit critical section. + */ +typedef void (* nrf_802154_sl_crit_sect_exit_t)(void); + +/** + * @brief Structure that holds interface of Radio Scheduler critical sections. + */ +typedef struct +{ + nrf_802154_sl_crit_sect_enter_t enter; + nrf_802154_sl_crit_sect_exit_t exit; +} nrf_802154_sl_crit_sect_interface_t; + +/** + * @brief Initializes the RSCH critical section module. + */ +void nrf_802154_rsch_crit_sect_init( + const nrf_802154_sl_crit_sect_interface_t * p_crit_sect_interface); + +/** + * @brief Requests the priority level from RSCH through the critical section module. + * + * @param[in] prio Requested priority level. + */ +void nrf_802154_rsch_crit_sect_prio_request(rsch_prio_t prio); + +/** + * @brief Notifies the core that the approved RSCH priority has changed. + * + * @note This function is called from the critical section context and does not preempt + * other critical sections. + * + * @param[in] prio Approved priority level. + */ +extern void nrf_802154_rsch_crit_sect_prio_changed(rsch_prio_t prio); + +/** + *@} + **/ + +#endif // NRF_802154_RSCH_CRIT_SECT_H__ diff --git a/nrf_802154_sl/include/rsch/nrf_802154_rsch_prio_drop.h b/nrf_802154_sl/include/rsch/nrf_802154_rsch_prio_drop.h new file mode 100644 index 0000000..f5dc8cd --- /dev/null +++ b/nrf_802154_sl/include/rsch/nrf_802154_rsch_prio_drop.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_802154_RSCH_PRIO_DROP_H__ +#define NRF_802154_RSCH_PRIO_DROP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initializes the notification module. + */ +void nrf_802154_rsch_prio_drop_init(void); + +/** + * @brief Requests the stop of the high frequency clock. + * + * @note This function must be called through this module to prevent calling it from the arbiter + * context. + */ +void nrf_802154_rsch_prio_drop_hfclk_stop(void); + +/** + * @brief Terminates the requesting of the high frequency clock stop procedure. + * + * Function used to to terminate the HFClk stop procedure requested by the previous call to + * @rev nrf_802154_rsch_prio_drop_hfclk_stop. The HFClk stop procedure is terminated only if it has + * not been started. + */ +void nrf_802154_rsch_prio_drop_hfclk_stop_terminate(void); + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_802154_RSCH_PRIO_DROP_H__ diff --git a/src/rsch/raal/nrf_raal_api.h b/nrf_802154_sl/include/rsch/raal/nrf_raal_api.h similarity index 67% rename from src/rsch/raal/nrf_raal_api.h rename to nrf_802154_sl/include/rsch/raal/nrf_raal_api.h index bb09ee4..d19ee62 100644 --- a/src/rsch/raal/nrf_raal_api.h +++ b/nrf_802154_sl/include/rsch/raal/nrf_raal_api.h @@ -1,33 +1,40 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /** * @brief Module that defines the Radio Arbiter Abstraction Layer interface. * diff --git a/nrf_802154_sl/include/rsch/raal/nrf_raal_config.h b/nrf_802154_sl/include/rsch/raal/nrf_raal_config.h new file mode 100644 index 0000000..13eb745 --- /dev/null +++ b/nrf_802154_sl/include/rsch/raal/nrf_raal_config.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_RAAL_CONFIG_H__ +#define NRF_RAAL_CONFIG_H__ + +#ifdef NRF_802154_PROJECT_CONFIG +#include NRF_802154_PROJECT_CONFIG +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_raal_config RAAL configuration + * @{ + * @ingroup nrf_802154 + * @brief Configuration of Radio Arbiter Abstraction Layer. + */ + +/** + * @def NRF_RAAL_MAX_CLEAN_UP_TIME_US + * + * The maximum time in which the radio driver must do any clean-up actions on the RADIO peripheral + * and stop using it. + * + */ +#ifndef NRF_RAAL_MAX_CLEAN_UP_TIME_US +#define NRF_RAAL_MAX_CLEAN_UP_TIME_US 91 +#endif + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_RAAL_CONFIG_H__ diff --git a/src/nrf_802154_timer_coord.h b/nrf_802154_sl/include/timer/nrf_802154_timer_coord.h similarity index 54% rename from src/nrf_802154_timer_coord.h rename to nrf_802154_sl/include/timer/nrf_802154_timer_coord.h index c7f8754..d34581c 100644 --- a/src/nrf_802154_timer_coord.h +++ b/nrf_802154_sl/include/timer/nrf_802154_timer_coord.h @@ -1,31 +1,39 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/timer_scheduler/nrf_802154_timer_sched.h b/nrf_802154_sl/include/timer/nrf_802154_timer_sched.h similarity index 72% rename from src/timer_scheduler/nrf_802154_timer_sched.h rename to nrf_802154_sl/include/timer/nrf_802154_timer_sched.h index 86021c2..43f3137 100644 --- a/src/timer_scheduler/nrf_802154_timer_sched.h +++ b/nrf_802154_sl/include/timer/nrf_802154_timer_sched.h @@ -1,31 +1,39 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/nrf_802154_sl/open/src/nrf_802154_sl_ant_div.c b/nrf_802154_sl/open/src/nrf_802154_sl_ant_div.c new file mode 100644 index 0000000..e56d260 --- /dev/null +++ b/nrf_802154_sl/open/src/nrf_802154_sl_ant_div.c @@ -0,0 +1,159 @@ +/* Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * @brief 802.15.4 antenna diversity module. + */ + +#include "nrf_802154_sl_ant_div.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void nrf_802154_sl_ant_div_cfg_set(const nrf_802154_sl_ant_div_cfg_t * p_cfg) +{ + (void)p_cfg; +} + +bool nrf_802154_sl_ant_div_cfg_get(nrf_802154_sl_ant_div_cfg_t * p_cfg) +{ + (void)p_cfg; + + return false; +} + +bool nrf_802154_sl_ant_div_cfg_mode_set(nrf_802154_sl_ant_div_op_t op, + nrf_802154_sl_ant_div_mode_t mode) +{ + (void)op; + (void)mode; + + return false; +} + +nrf_802154_sl_ant_div_mode_t nrf_802154_sl_ant_div_cfg_mode_get(nrf_802154_sl_ant_div_op_t op) +{ + (void)op; + + return NRF_802154_SL_ANT_DIV_MODE_DISABLED; +} + +bool nrf_802154_sl_ant_div_cfg_antenna_set(nrf_802154_sl_ant_div_op_t op, + nrf_802154_sl_ant_div_antenna_t antenna) +{ + (void)op; + (void)antenna; + + return false; +} + +nrf_802154_sl_ant_div_antenna_t nrf_802154_sl_ant_div_cfg_antenna_get(nrf_802154_sl_ant_div_op_t op) +{ + (void)op; + + return NRF_802154_SL_ANT_DIV_ANTENNA_NONE; +} + +bool nrf_802154_sl_ant_div_init(void) +{ + return false; +} + +bool nrf_802154_sl_ant_div_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna) +{ + (void)antenna; + + return false; +} + +nrf_802154_sl_ant_div_antenna_t nrf_802154_sl_ant_div_antenna_get(void) +{ + return NRF_802154_SL_ANT_DIV_ANTENNA_NONE; +} + +nrf_802154_sl_ant_div_antenna_t nrf_802154_sl_ant_div_last_rx_best_antenna_get(void) +{ + return NRF_802154_SL_ANT_DIV_ANTENNA_NONE; +} + +bool nrf_802154_sl_ant_div_rx_frame_started_notify(void) +{ + return false; +} + +void nrf_802154_sl_ant_div_rx_frame_received_notify(void) +{ + // Intenionally empty +} + +void nrf_802154_sl_ant_div_rx_aborted_notify(void) +{ + // Intentionally empty +} + +void nrf_802154_sl_ant_div_rx_preamble_timeout_notify(void) +{ + // Intentionally empty +} + +void nrf_802154_sl_ant_div_rx_preamble_detected_notify(void) +{ + // Intentionally empty +} + +void nrf_802154_sl_ant_div_energy_detection_requested_notify(uint32_t * p_ed_time) +{ + (void)p_ed_time; +} + +void nrf_802154_sl_ant_div_energy_detection_aborted_notify(void) +{ + // Intentionally empty +} + +bool nrf_802154_sl_ant_div_energy_detection_finished_notify(void) +{ + return false; +} + +void nrf_802154_sl_ant_div_rx_started_notify(void) +{ + // Intentionally empty +} + +void nrf_802154_sl_ant_div_txack_notify(void) +{ + // Intentionally empty +} + +#ifdef __cplusplus +} +#endif diff --git a/nrf_802154_sl/open/src/nrf_802154_sl_coex.c b/nrf_802154_sl/open/src/nrf_802154_sl_coex.c new file mode 100644 index 0000000..30ce930 --- /dev/null +++ b/nrf_802154_sl/open/src/nrf_802154_sl_coex.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "nrf_802154_sl_coex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +nrf_802154_wifi_coex_interface_type_id_t nrf_802154_wifi_coex_interface_type_id_get(void) +{ + return NRF_802154_WIFI_COEX_IF_NONE; +} + +void nrf_802154_wifi_coex_cfg_3wire_get(nrf_802154_wifi_coex_3wire_if_config_t * p_cfg) +{ + (void)p_cfg; + + return; +} + +void nrf_802154_wifi_coex_cfg_3wire_set(const nrf_802154_wifi_coex_3wire_if_config_t * p_cfg) +{ + (void)p_cfg; + + return; +} + +nrf_802154_wifi_coex_ret_t nrf_802154_wifi_coex_init(void) +{ + return NRF_802154_WIFI_COEX_RET_DEFAULT_ERR; +} + +bool nrf_802154_wifi_coex_is_enabled(void) +{ + return false; +} + +#ifdef __cplusplus +} +#endif diff --git a/nrf_802154_sl/open/src/nrf_802154_sl_fem.c b/nrf_802154_sl/open/src/nrf_802154_sl_fem.c new file mode 100644 index 0000000..ced69dc --- /dev/null +++ b/nrf_802154_sl/open/src/nrf_802154_sl_fem.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "nrf.h" + +#include "fem/nrf_fem_protocol_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t nrf_802154_fal_pa_configuration_set(const nrf_802154_fal_event_t * const p_activate_event, + const nrf_802154_fal_event_t * const p_deactivate_event) +{ + (void)p_activate_event; + (void)p_deactivate_event; + + return NRFX_ERROR_FORBIDDEN; +} + +int32_t nrf_802154_fal_pa_configuration_clear(void) +{ + return NRFX_ERROR_FORBIDDEN; +} + +int32_t nrf_802154_fal_lna_configuration_set(const nrf_802154_fal_event_t * const p_activate_event, + const nrf_802154_fal_event_t * const p_deactivate_event) +{ + (void)p_activate_event; + (void)p_deactivate_event; + + return NRFX_ERROR_FORBIDDEN; +} + +int32_t nrf_802154_fal_lna_configuration_clear(void) +{ + return NRFX_ERROR_FORBIDDEN; +} + +void nrf_802154_fal_deactivate_now(nrf_fal_functionality_t type) +{ + (void)type; +} + +#if defined(NRF52_SERIES) +// TODO: Uncomment this code when API is portable to nRF53 +int32_t nrf_802154_fal_abort_set(uint32_t event, nrf_ppi_channel_group_t group) +{ + return NRFX_ERROR_FORBIDDEN; +} + +int32_t nrf_802154_fal_abort_extend(nrf_ppi_channel_t channel_to_add, + nrf_ppi_channel_group_t group) +{ + return NRFX_ERROR_FORBIDDEN; +} + +int32_t nrf_802154_fal_abort_reduce(nrf_ppi_channel_t channel_to_remove, + nrf_ppi_channel_group_t group) +{ + return NRFX_ERROR_FORBIDDEN; +} + +int32_t nrf_802154_fal_abort_clear(void) +{ + return NRFX_ERROR_FORBIDDEN; +} + +#endif // NRF52_SERIES + +void nrf_802154_fal_cleanup(void) +{ + // Intentionally empty +} + +void nrf_802154_fal_pa_is_configured(int8_t * const p_gain) +{ + (void)p_gain; +} + +#if defined(NRF52_SERIES) +// TODO: Uncomment this code when API is portable to nRF53 +bool nrf_fem_prepare_powerdown(NRF_TIMER_Type * p_instance, + uint32_t compare_channel, + nrf_ppi_channel_t ppi_id) +{ + (void)p_instance; + (void)compare_channel; + (void)ppi_id; + + return false; +} + +#endif // NRF52_SERIES + +int8_t nrf_802154_fal_tx_power_get(const uint8_t channel, const int8_t power) +{ + (void)channel; + + return power; +} + +#ifdef __cplusplus +} +#endif diff --git a/nrf_802154_sl/open/src/nrf_802154_sl_log.c b/nrf_802154_sl/open/src/nrf_802154_sl_log.c new file mode 100644 index 0000000..6dd9e6a --- /dev/null +++ b/nrf_802154_sl/open/src/nrf_802154_sl_log.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "nrf_802154_sl_log.h" + +/** + * @brief Buffer used to store debug log messages. + */ +volatile uint32_t g_nrf_802154_sl_log_buffer[NRF_802154_SL_DEBUG_LOG_BUFFER_LEN]; + +/** + * @brief Index of the log buffer pointing to the element that should be filled with next log message. + */ +volatile uint32_t gp_nrf_802154_sl_log_ptr = 0; + +void nrf_802154_sl_log_init(void) +{ + /* intentionally empty */ +} diff --git a/nrf_802154_sl/open/src/nrf_802154_sl_rsch.c b/nrf_802154_sl/open/src/nrf_802154_sl_rsch.c new file mode 100644 index 0000000..2a8f7b4 --- /dev/null +++ b/nrf_802154_sl/open/src/nrf_802154_sl_rsch.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "nrf_802154_sl_rsch.h" + +#include +#include +#include +#include + +#include "rsch/nrf_802154_rsch.h" +#include "platform/clock/nrf_802154_clock.h" + +static rsch_prio_t m_prev_prio; +static bool m_ready; + +/** + * @brief Notifies the core that the approved RSCH priority has changed. + * + * @note This function is called from the critical section context and does not preempt + * other critical sections. + * + * @param[in] prio Approved priority level. + */ +extern void nrf_802154_rsch_crit_sect_prio_changed(rsch_prio_t prio); + +/*************************************************************************************************** + * Public API + **************************************************************************************************/ + +void nrf_802154_rsch_init(void) +{ + m_ready = false; + m_prev_prio = RSCH_PRIO_IDLE; +} + +void nrf_802154_rsch_uninit(void) +{ + // Intenionally empty +} + +void nrf_802154_rsch_continuous_ended(void) +{ + // Intentionally empty +} + +bool nrf_802154_rsch_timeslot_request(uint32_t length_us) +{ + (void)length_us; + + assert(m_ready); + + return true; +} + +bool nrf_802154_rsch_timeslot_is_requested(void) +{ + return false; +} + +bool nrf_802154_rsch_prec_is_approved(rsch_prec_t prec, rsch_prio_t prio) +{ + return prio == RSCH_PRIO_IDLE ? true : m_ready; +} + +uint32_t nrf_802154_rsch_timeslot_us_left_get(void) +{ + return UINT32_MAX; +} + +void nrf_802154_clock_hfclk_ready(void) +{ + m_ready = true; + nrf_802154_rsch_crit_sect_prio_changed(RSCH_PRIO_MAX); +} + +void nrf_802154_rsch_crit_sect_prio_request(rsch_prio_t prio) +{ + if (m_prev_prio != prio) + { + if (prio == RSCH_PRIO_IDLE) + { + nrf_802154_clock_hfclk_stop(); + + assert(m_ready); + + m_ready = false; + + nrf_802154_rsch_crit_sect_prio_changed(RSCH_PRIO_IDLE); + } + else if (m_prev_prio == RSCH_PRIO_IDLE) + { + assert(!m_ready); + + nrf_802154_clock_hfclk_start(); + } + else + { + // Intentionally empty + } + + m_prev_prio = prio; + } +} + +void nrf_802154_rsch_prio_drop_init(void) +{ + // Intentionally empty +} + +void nrf_802154_rsch_crit_sect_init(void) +{ + // Intentionally empty +} + +void nrf_802154_critical_section_rsch_enter(void) +{ + // Intentionally empty +} + +void nrf_802154_critical_section_rsch_exit(void) +{ + // Intentionally empty +} + +bool nrf_802154_critical_section_rsch_event_is_pending(void) +{ + return false; +} + +bool nrf_802154_rsch_delayed_timeslot_request(const rsch_dly_ts_param_t * p_dly_ts_param) +{ + (void)p_dly_ts_param; + + return false; +} + +bool nrf_802154_rsch_delayed_timeslot_cancel(rsch_dly_ts_id_t dly_ts_id) +{ + (void)dly_ts_id; + + return false; +} + +bool nrf_802154_rsch_delayed_timeslot_priority_update(rsch_dly_ts_id_t dly_ts_id, + rsch_prio_t dly_ts_prio) +{ + (void)dly_ts_id; + (void)dly_ts_prio; + + return false; +} diff --git a/nrf_802154_sl/open/src/nrf_802154_sl_timer.c b/nrf_802154_sl/open/src/nrf_802154_sl_timer.c new file mode 100644 index 0000000..33b6299 --- /dev/null +++ b/nrf_802154_sl/open/src/nrf_802154_sl_timer.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "nrf_802154_sl_utils.h" + +#include +#include + +#include +#include + +#include "timer/nrf_802154_timer_coord.h" +#include "timer/nrf_802154_timer_sched.h" + +static void timeout_handler(struct k_timer * timer_id); + +K_TIMER_DEFINE(timer, timeout_handler, NULL); + +void nrf_802154_timer_coord_init(void) +{ + // Intentionally empty +} + +void nrf_802154_timer_coord_uninit(void) +{ + // Intentionally empty +} + +void nrf_802154_timer_coord_start(void) +{ + // Intentionally empty +} + +void nrf_802154_timer_coord_stop(void) +{ + // Intentionally empty +} + +void nrf_802154_timer_sched_init(void) +{ + BUILD_ASSERT(CONFIG_SYS_CLOCK_TICKS_PER_SEC == NRF_802154_SL_RTC_FREQUENCY); +} + +void nrf_802154_timer_sched_deinit(void) +{ + // Intentionally empty +} + +uint32_t nrf_802154_timer_sched_time_get(void) +{ + return NRF_802154_SL_RTC_TICKS_TO_US(k_uptime_ticks()); +} + +void nrf_802154_timer_sched_add(nrf_802154_timer_t * p_timer, bool round_up) +{ + (void)round_up; + assert(!(p_timer->p_next)); // Only one timer is allowed to run at a time. + + uint32_t now = nrf_802154_timer_sched_time_get(); + uint32_t target = p_timer->t0 + p_timer->dt - now; + + k_timer_user_data_set(&timer, (void *)p_timer->callback); // Passing arguments is not supported. + k_timer_start(&timer, K_USEC(target), K_NO_WAIT); +} + +void nrf_802154_timer_sched_remove(nrf_802154_timer_t * p_timer, bool * p_was_running) +{ + if (k_timer_status_get(&timer) > 0) + { + /* Timer has expired. */ + if (p_was_running) + { + *p_was_running = false; + } + } + else if (k_timer_remaining_get(&timer) == 0) + { + /* Timer was stopped (by someone else) before expiring. */ + if (p_was_running) + { + *p_was_running = false; + } + } + else + { + /* Timer is still running. */ + k_timer_stop(&timer); + if (p_was_running) + { + *p_was_running = true; + } + } +} + +bool nrf_802154_timer_sched_time_is_in_future(uint32_t now, uint32_t t0, uint32_t dt) +{ + (void)now; + (void)t0; + (void)dt; + return false; +} + +static void timeout_handler(struct k_timer * timer_id) +{ + nrf_802154_timer_callback_t callback = + (nrf_802154_timer_callback_t)k_timer_user_data_get(timer_id); + + callback(NULL); // Passing arguments is not supported. +} + +bool nrf_802154_timer_sched_is_running(nrf_802154_timer_t * p_timer) +{ + (void)p_timer; + return k_timer_status_get(&timer) < 0; +} + +void nrf_802154_lp_timer_init(void) +{ + // Intentionally empty +} + +void nrf_802154_lp_timer_deinit(void) +{ + // Intentionally empty +} + +void nrf_802154_lp_timer_critical_section_enter(void) +{ + // Intentionally empty +} + +void nrf_802154_lp_timer_critical_section_exit(void) +{ + // Intentionally empty +} diff --git a/nrf_802154_sl/platform/clock/nrf_802154_clock.c b/nrf_802154_sl/platform/clock/nrf_802154_clock.c new file mode 100644 index 0000000..0b1684b --- /dev/null +++ b/nrf_802154_sl/platform/clock/nrf_802154_clock.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements the nrf 802.15.4 HF Clock abstraction with nrfx driver. + * + * This implementation uses clock driver implementation from nrfx. + */ + +#include "nrf_802154_clock.h" + +#include + +#include +#include + +static void clock_event_handler(nrfx_clock_evt_type_t event) +{ + if (event == NRFX_CLOCK_EVT_HFCLK_STARTED) + { + nrf_802154_clock_hfclk_ready(); + } + + if (event == NRFX_CLOCK_EVT_LFCLK_STARTED) + { + nrf_802154_clock_lfclk_ready(); + } +} + +void nrf_802154_clock_init(void) +{ + nrfx_clock_init(&clock_event_handler); + nrfx_clock_enable(); +} + +void nrf_802154_clock_deinit(void) +{ + nrfx_clock_disable(); + nrfx_clock_uninit(); +} + +void nrf_802154_clock_hfclk_start(void) +{ + nrfx_clock_start(NRF_CLOCK_DOMAIN_HFCLK); +} + +void nrf_802154_clock_hfclk_stop(void) +{ + nrfx_clock_stop(NRF_CLOCK_DOMAIN_HFCLK); +} + +bool nrf_802154_clock_hfclk_is_running(void) +{ + return nrfx_clock_is_running(NRF_CLOCK_DOMAIN_HFCLK, NULL); +} + +void nrf_802154_clock_lfclk_start(void) +{ + nrfx_clock_start(NRF_CLOCK_DOMAIN_LFCLK); +} + +void nrf_802154_clock_lfclk_stop(void) +{ + nrfx_clock_stop(NRF_CLOCK_DOMAIN_LFCLK); +} + +bool nrf_802154_clock_lfclk_is_running(void) +{ + return nrfx_clock_is_running(NRF_CLOCK_DOMAIN_LFCLK, NULL); +} + +__WEAK void nrf_802154_clock_hfclk_ready(void) +{ + // Intentionally empty. +} + +__WEAK void nrf_802154_clock_lfclk_ready(void) +{ + // Intentionally empty. +} diff --git a/nrf_802154_sl/platform/clock/nrf_802154_clock_mpsl.c b/nrf_802154_sl/platform/clock/nrf_802154_clock_mpsl.c new file mode 100644 index 0000000..8eb5618 --- /dev/null +++ b/nrf_802154_sl/platform/clock/nrf_802154_clock_mpsl.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements the nrf 802.15.4 HF Clock abstraction with MPSL API. + * + * This implementation uses clock driver implementation from MPSL. + */ + +#include "nrf_802154_clock.h" + +#include +#include + +#include "mpsl.h" +#include "mpsl_clock.h" + +static bool m_clock_requested = false; + +void nrf_802154_clock_init(void) +{ + // Intentionally empty. Clock initialization is performed when MPSL is initialized. +} + +void nrf_802154_clock_deinit(void) +{ + if (m_clock_requested) + { + nrf_802154_clock_hfclk_stop(); + } +} + +void nrf_802154_clock_hfclk_start(void) +{ + (void)mpsl_clock_hfclk_request(nrf_802154_clock_hfclk_ready); + + m_clock_requested = true; +} + +void nrf_802154_clock_hfclk_stop(void) +{ + (void)mpsl_clock_hfclk_release(); + + m_clock_requested = false; +} + +bool nrf_802154_clock_hfclk_is_running(void) +{ + uint32_t hfclk_is_running = mpsl_clock_hfclk_is_running(&hfclk_is_running); + + return (bool)hfclk_is_running; +} + +void nrf_802154_clock_lfclk_start(void) +{ + // Low frequency clock is started when MPSL is initialized. + bool is_initialized = mpsl_is_initialized(); + + assert(is_initialized); + + (void)is_initialized; + + nrf_802154_clock_lfclk_ready(); +} + +void nrf_802154_clock_lfclk_stop(void) +{ + // Intentionally empty. MPSL does not support stopping low frequency clock. +} + +bool nrf_802154_clock_lfclk_is_running(void) +{ + // Low frequency clock is started when MPSL is initialized and it is kept running as long as MPSL itself. + return mpsl_is_initialized(); +} + +__WEAK void nrf_802154_clock_hfclk_ready(void) +{ + // Intentionally empty. +} + +__WEAK void nrf_802154_clock_lfclk_ready(void) +{ + // Intentionally empty. +} diff --git a/nrf_802154_sl/platform/clock/nrf_802154_clock_zephyr.c b/nrf_802154_sl/platform/clock/nrf_802154_clock_zephyr.c new file mode 100644 index 0000000..10856ec --- /dev/null +++ b/nrf_802154_sl/platform/clock/nrf_802154_clock_zephyr.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic + */ + +/** + * @file + * This file implements the nrf 802.15.4 HF Clock abstraction with Zephyr API. + * + * This implementation uses Zephyr API for clock management. + */ + +#include + +#include + +#include +#include +#include + +static bool hfclk_is_running; +static bool lfclk_is_running; +static struct onoff_client hfclk_cli; +static struct onoff_client lfclk_cli; + +void nrf_802154_clock_init(void) +{ + /* Intentionally empty. */ +} + +void nrf_802154_clock_deinit(void) +{ + /* Intentionally empty. */ +} + +static void hfclk_on_callback(struct onoff_manager * mgr, + struct onoff_client * cli, + uint32_t state, + int res) +{ + hfclk_is_running = true; + nrf_802154_clock_hfclk_ready(); +} + +void nrf_802154_clock_hfclk_start(void) +{ + int ret; + struct onoff_manager * mgr = + z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF); + + __ASSERT_NO_MSG(mgr != NULL); + + sys_notify_init_callback(&hfclk_cli.notify, hfclk_on_callback); + + ret = onoff_request(mgr, &hfclk_cli); + __ASSERT_NO_MSG(ret >= 0); +} + +void nrf_802154_clock_hfclk_stop(void) +{ + int ret; + struct onoff_manager * mgr = + z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF); + + __ASSERT_NO_MSG(mgr != NULL); + + ret = onoff_cancel_or_release(mgr, &hfclk_cli); + __ASSERT_NO_MSG(ret >= 0); + hfclk_is_running = false; +} + +bool nrf_802154_clock_hfclk_is_running(void) +{ + return hfclk_is_running; +} + +static void lfclk_on_callback(struct onoff_manager * mgr, + struct onoff_client * cli, + uint32_t state, + int res) +{ + lfclk_is_running = true; + nrf_802154_clock_lfclk_ready(); +} + +void nrf_802154_clock_lfclk_start(void) +{ + int ret; + struct onoff_manager * mgr = + z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF); + + __ASSERT_NO_MSG(mgr != NULL); + + sys_notify_init_callback(&lfclk_cli.notify, lfclk_on_callback); + + ret = onoff_request(mgr, &lfclk_cli); + __ASSERT_NO_MSG(ret >= 0); +} + +void nrf_802154_clock_lfclk_stop(void) +{ + int ret; + struct onoff_manager * mgr = + z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF); + + __ASSERT_NO_MSG(mgr != NULL); + + ret = onoff_cancel_or_release(mgr, &lfclk_cli); + __ASSERT_NO_MSG(ret >= 0); + lfclk_is_running = false; +} + +bool nrf_802154_clock_lfclk_is_running(void) +{ + return lfclk_is_running; +} + +__WEAK void nrf_802154_clock_hfclk_ready(void) +{ + /* Intentionally empty. */ +} + +__WEAK void nrf_802154_clock_lfclk_ready(void) +{ + /* Intentionally empty. */ +} diff --git a/nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_crit_sect.c b/nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_crit_sect.c new file mode 100644 index 0000000..b5ce53f --- /dev/null +++ b/nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_crit_sect.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file contains system-agnostic implementation of the nRF 802.15.4 GPIOTE + * critical section abstraction. + */ + +#include "platform/gpiote/nrf_802154_gpiote.h" + +#include "hal/nrf_gpio.h" +#include "nrf_802154_sl_utils.h" +#include "platform/irq/nrf_802154_irq.h" + +static volatile bool m_gpiote_irq_enabled; ///< Whether the GPIOTE interrupt was turned on before entering the first critical section. +static volatile uint32_t m_gpiote_irq_disabled_cnt; ///< Counter of how many times GPIOTE interrupt was disabled while entering critical section. + +void nrf_802154_gpiote_critical_section_enter(void) +{ + nrf_802154_sl_mcu_critical_state_t mcu_cs; + uint32_t cnt; + + nrf_802154_sl_mcu_critical_enter(mcu_cs); + cnt = m_gpiote_irq_disabled_cnt; + + if (cnt == 0U) + { + m_gpiote_irq_enabled = nrf_802154_irq_is_enabled(GPIOTE_IRQn); + nrf_802154_irq_disable(GPIOTE_IRQn); + } + + cnt++; + m_gpiote_irq_disabled_cnt = cnt; + + nrf_802154_sl_mcu_critical_exit(mcu_cs); +} + +void nrf_802154_gpiote_critical_section_exit(void) +{ + nrf_802154_sl_mcu_critical_state_t mcu_cs; + uint32_t cnt; + + nrf_802154_sl_mcu_critical_enter(mcu_cs); + + cnt = m_gpiote_irq_disabled_cnt; + cnt--; + + if (cnt == 0U) + { + if (m_gpiote_irq_enabled) + { + nrf_802154_irq_enable(GPIOTE_IRQn); + } + } + + m_gpiote_irq_disabled_cnt = cnt; + + nrf_802154_sl_mcu_critical_exit(mcu_cs); +} \ No newline at end of file diff --git a/nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_none.c b/nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_none.c new file mode 100644 index 0000000..b1bd743 --- /dev/null +++ b/nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_none.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file contains implementation of the nRF 802.15.4 GPIOTE abstraction. + * + * This implementation is intended to be used in bare-metal applications. Developer of such application can: + * - use this implementation unmodified when GPIOTE peripheral is to be used only by the nRF 802.15.4 Radio Driver + * - use this implementation as a reference for developing own platform port. In this case additional code can be put in GPIOTE_IRQHandler + * allowing handling interrupts coming from sources not related to nRF 802.15.4 driver. + * + */ + +#include "platform/gpiote/nrf_802154_gpiote.h" + +#include +#include +#include + +#include "hal/nrf_gpiote.h" +#include "nrf_802154_sl_coex.h" +#include "nrf_802154_irq.h" + +#define GPIOTE_IRQ_PRIORITY 4 + +static uint32_t m_gpio_pin; ///< Number of GPIO pin associated with the Grant line. +static uint32_t m_gpiote_ch_id; ///< Number of GPIOTE channel associated with the Grant line. + +void nrf_802154_gpiote_init(void) +{ + switch (nrf_802154_wifi_coex_interface_type_id_get()) + { + case NRF_802154_WIFI_COEX_IF_NONE: + return; + + case NRF_802154_WIFI_COEX_IF_3WIRE: + { + nrf_802154_wifi_coex_3wire_if_config_t cfg; + + nrf_802154_wifi_coex_cfg_3wire_get(&cfg); + + m_gpio_pin = cfg.grant_cfg.gpio_pin; + m_gpiote_ch_id = cfg.grant_cfg.gpiote_ch_id; + assert(m_gpio_pin != COEX_GPIO_PIN_INVALID); + + NRF_GPIOTE->CONFIG[m_gpiote_ch_id] = + ((GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos) + | (m_gpio_pin << GPIOTE_CONFIG_PSEL_Pos) + | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)); + NRF_GPIOTE->INTENSET = (1 << m_gpiote_ch_id); + + nrf_802154_irq_init(GPIOTE_IRQn, + GPIOTE_IRQ_PRIORITY, + nrf_802154_wifi_coex_gpiote_irqhandler); + nrf_802154_irq_enable(GPIOTE_IRQn); + break; + } + + default: + assert(false); + } +} + +void nrf_802154_gpiote_deinit(void) +{ + nrf_802154_irq_clear_pending(GPIOTE_IRQn); + nrf_802154_irq_disable(GPIOTE_IRQn); +} + +void GPIOTE_IRQHandler(void) +{ + if (NRF_GPIOTE->EVENTS_IN[m_gpiote_ch_id]) + { + NRF_GPIOTE->EVENTS_IN[m_gpiote_ch_id] = 0; + nrf_802154_wifi_coex_gpiote_irqhandler(); + } +} diff --git a/nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_zephyr.c b/nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_zephyr.c new file mode 100644 index 0000000..bdc5f25 --- /dev/null +++ b/nrf_802154_sl/platform/gpiote/nrf_802154_gpiote_zephyr.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic + */ + +/** + * @file + * This file contains implementation of the nRF 802.15.4 GPIOTE abstraction. + * + * This implementation is to be used with Zephyr RTOS. + * + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +static const struct device * dev; +static struct gpio_callback grant_cb; +static uint32_t pin_number = COEX_GPIO_PIN_INVALID; + +static void gpiote_irq_handler(const struct device * gpiob, struct gpio_callback * cb, + uint32_t pins) +{ + ARG_UNUSED(gpiob); + ARG_UNUSED(cb); + ARG_UNUSED(pins); + + nrf_802154_wifi_coex_gpiote_irqhandler(); +} + +void nrf_802154_gpiote_init(void) +{ + switch (nrf_802154_wifi_coex_interface_type_id_get()) + { + case NRF_802154_WIFI_COEX_IF_NONE: + return; + + case NRF_802154_WIFI_COEX_IF_3WIRE: { + nrf_802154_wifi_coex_3wire_if_config_t cfg; + + nrf_802154_wifi_coex_cfg_3wire_get(&cfg); + + pin_number = cfg.grant_cfg.gpio_pin; + __ASSERT_NO_MSG(pin_number != COEX_GPIO_PIN_INVALID); + + bool use_port_1 = (pin_number > P0_PIN_NUM); + + /* Convert to the Zephyr primitive */ + pin_number = use_port_1 ? pin_number - P0_PIN_NUM : pin_number; + + uint32_t pull_up_down = cfg.grant_cfg.active_high ? + GPIO_PULL_UP : + GPIO_PULL_DOWN; + +#if DT_NODE_EXISTS(DT_NODELABEL(gpio1)) + dev = device_get_binding(use_port_1 ? + DT_LABEL(DT_NODELABEL(gpio1)) : + DT_LABEL(DT_NODELABEL(gpio0))); +#else + dev = device_get_binding(DT_LABEL(DT_NODELABEL(gpio0))); +#endif + __ASSERT_NO_MSG(dev != NULL); + + gpio_pin_configure(dev, pin_number, GPIO_INPUT | pull_up_down); + + gpio_init_callback(&grant_cb, gpiote_irq_handler, + BIT(pin_number)); + gpio_add_callback(dev, &grant_cb); + + gpio_pin_interrupt_configure(dev, pin_number, + GPIO_INT_EDGE_BOTH); + break; + } + + default: + __ASSERT_NO_MSG(false); + } +} + +void nrf_802154_gpiote_deinit(void) +{ + switch (nrf_802154_wifi_coex_interface_type_id_get()) + { + case NRF_802154_WIFI_COEX_IF_NONE: + break; + + case NRF_802154_WIFI_COEX_IF_3WIRE: + gpio_pin_interrupt_configure(dev, pin_number, GPIO_INT_DISABLE); + gpio_remove_callback(dev, &grant_cb); + pin_number = COEX_GPIO_PIN_INVALID; + break; + + default: + __ASSERT_NO_MSG(false); + } +} diff --git a/src/platform/hp_timer/nrf_802154_hp_timer.c b/nrf_802154_sl/platform/hp_timer/nrf_802154_hp_timer.c similarity index 51% rename from src/platform/hp_timer/nrf_802154_hp_timer.c rename to nrf_802154_sl/platform/hp_timer/nrf_802154_hp_timer.c index eadce20..a4bf90c 100644 --- a/src/platform/hp_timer/nrf_802154_hp_timer.c +++ b/nrf_802154_sl/platform/hp_timer/nrf_802154_hp_timer.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -37,17 +38,17 @@ * */ -#include "nrf_802154_hp_timer.h" +#include "platform/hp_timer/nrf_802154_hp_timer.h" #include #include #include -#include -#include +#include "nrf.h" +#include "hal/nrf_timer.h" -#include "nrf_802154_config.h" -#include "nrf_802154_peripherals.h" +#include "nrf_802154_sl_config.h" +#include "nrf_802154_sl_periphs.h" /**@brief Timer instance. */ #define TIMER NRF_802154_HIGH_PRECISION_TIMER_INSTANCE @@ -72,7 +73,7 @@ static uint32_t m_unexpected_sync; static inline uint32_t timer_time_get(void) { nrf_timer_task_trigger(TIMER, TIMER_CC_CAPTURE_TASK); - return nrf_timer_cc_read(TIMER, TIMER_CC_CAPTURE); + return nrf_timer_cc_get(TIMER, TIMER_CC_CAPTURE); } void nrf_802154_hp_timer_init(void) @@ -82,29 +83,24 @@ void nrf_802154_hp_timer_init(void) void nrf_802154_hp_timer_deinit(void) { - nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_SHUTDOWN); + // Intentionally empty } void nrf_802154_hp_timer_start(void) { -#if !RAAL_SOFTDEVICE && !RAAL_SIMULATOR && !RAAL_REM - nrf_timer_mode_set(TIMER, NRF_TIMER_MODE_TIMER); + // This resource is shared, so its configuration must be restored before every use + // instead of setting in initialization only. nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32); - nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_1MHz); - nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_START); -#endif // !RAAL_SOFTDEVICE && !RAAL_SIMULATOR && !RAAL_REM } void nrf_802154_hp_timer_stop(void) { -#if !RAAL_SOFTDEVICE && !RAAL_SIMULATOR && !RAAL_REM - nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_SHUTDOWN); -#endif // !RAAL_SOFTDEVICE && !RAAL_SIMULATOR && !RAAL_REM + // Intentionally empty } uint32_t nrf_802154_hp_timer_sync_task_get(void) { - return (uint32_t)nrf_timer_task_address_get(TIMER, TIMER_CC_SYNC_TASK); + return nrf_timer_task_address_get(TIMER, TIMER_CC_SYNC_TASK); } void nrf_802154_hp_timer_sync_prepare(void) @@ -112,13 +108,13 @@ void nrf_802154_hp_timer_sync_prepare(void) uint32_t past_time = timer_time_get() - 1; m_unexpected_sync = past_time; - nrf_timer_cc_write(TIMER, TIMER_CC_SYNC, past_time); + nrf_timer_cc_set(TIMER, TIMER_CC_SYNC, past_time); } bool nrf_802154_hp_timer_sync_time_get(uint32_t * p_timestamp) { bool result = false; - uint32_t sync_time = nrf_timer_cc_read(TIMER, TIMER_CC_SYNC); + uint32_t sync_time = nrf_timer_cc_get(TIMER, TIMER_CC_SYNC); assert(p_timestamp != NULL); @@ -133,10 +129,15 @@ bool nrf_802154_hp_timer_sync_time_get(uint32_t * p_timestamp) uint32_t nrf_802154_hp_timer_timestamp_task_get(void) { - return (uint32_t)nrf_timer_task_address_get(TIMER, TIMER_CC_EVT_TASK); + return nrf_timer_task_address_get(TIMER, TIMER_CC_EVT_TASK); } uint32_t nrf_802154_hp_timer_timestamp_get(void) { - return nrf_timer_cc_read(TIMER, TIMER_CC_EVT); + return nrf_timer_cc_get(TIMER, TIMER_CC_EVT); +} + +uint32_t nrf_802154_hp_timer_current_time_get(void) +{ + return timer_time_get(); } diff --git a/src/platform/irq/nrf_802154_irq_baremetal.c b/nrf_802154_sl/platform/irq/nrf_802154_irq_baremetal.c similarity index 91% rename from src/platform/irq/nrf_802154_irq_baremetal.c rename to nrf_802154_sl/platform/irq/nrf_802154_irq_baremetal.c index 633d958..2f2c257 100644 --- a/src/platform/irq/nrf_802154_irq_baremetal.c +++ b/nrf_802154_sl/platform/irq/nrf_802154_irq_baremetal.c @@ -65,30 +65,30 @@ void nrf_802154_irq_init(uint32_t irqn, uint32_t prio, nrf_802154_isr_t isr) */ (void)isr; - NVIC_SetPriority((IRQn_Type)irqn, prio); - NVIC_ClearPendingIRQ((IRQn_Type)irqn); + NVIC_SetPriority(irqn, prio); + NVIC_ClearPendingIRQ(irqn); } void nrf_802154_irq_enable(uint32_t irqn) { - NVIC_EnableIRQ((IRQn_Type)irqn); + NVIC_EnableIRQ(irqn); } void nrf_802154_irq_disable(uint32_t irqn) { - NVIC_DisableIRQ((IRQn_Type)irqn); + NVIC_DisableIRQ(irqn); __DSB(); __ISB(); } void nrf_802154_irq_set_pending(uint32_t irqn) { - NVIC_SetPendingIRQ((IRQn_Type)irqn); + NVIC_SetPendingIRQ(irqn); } void nrf_802154_irq_clear_pending(uint32_t irqn) { - NVIC_ClearPendingIRQ((IRQn_Type)irqn); + NVIC_ClearPendingIRQ(irqn); } bool nrf_802154_irq_is_enabled(uint32_t irqn) @@ -100,5 +100,5 @@ bool nrf_802154_irq_is_enabled(uint32_t irqn) uint32_t nrf_802154_irq_priority_get(uint32_t irqn) { - return NVIC_GetPriority((IRQn_Type)irqn); + return NVIC_GetPriority(irqn); } diff --git a/src/platform/irq/nrf_802154_irq_zephyr.c b/nrf_802154_sl/platform/irq/nrf_802154_irq_zephyr.c similarity index 95% rename from src/platform/irq/nrf_802154_irq_zephyr.c rename to nrf_802154_sl/platform/irq/nrf_802154_irq_zephyr.c index ca7d93d..dd2c6fc 100644 --- a/src/platform/irq/nrf_802154_irq_zephyr.c +++ b/nrf_802154_sl/platform/irq/nrf_802154_irq_zephyr.c @@ -6,12 +6,14 @@ /** * @file - * This file implements the nrf 802.15.4 Interrupt Abstraction Layer with Zephyr API. + * This file implements the nrf 802.15.4 Interrupt Abstraction Layer with + * Zephyr API. */ #include #include +#include void nrf_802154_irq_init(uint32_t irqn, uint32_t prio, nrf_802154_isr_t isr) { diff --git a/src/platform/lp_timer/nrf_802154_lp_timer.c b/nrf_802154_sl/platform/lp_timer/nrf_802154_lp_timer.c similarity index 80% rename from src/platform/lp_timer/nrf_802154_lp_timer.c rename to nrf_802154_sl/platform/lp_timer/nrf_802154_lp_timer.c index 9736278..cb11616 100644 --- a/src/platform/lp_timer/nrf_802154_lp_timer.c +++ b/nrf_802154_sl/platform/lp_timer/nrf_802154_lp_timer.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -36,18 +37,18 @@ * */ -#include "nrf_802154_lp_timer.h" +#include "platform/lp_timer/nrf_802154_lp_timer.h" #include -#include -#include +#include "nrf.h" +#include "hal/nrf_rtc.h" #include "platform/clock/nrf_802154_clock.h" -#include "nrf_802154_config.h" -#include "nrf_802154_peripherals.h" -#include "nrf_802154_utils.h" #include "platform/irq/nrf_802154_irq.h" +#include "nrf_802154_sl_config.h" +#include "nrf_802154_sl_periphs.h" +#include "nrf_802154_sl_utils.h" #define RTC_LP_TIMER_COMPARE_CHANNEL 0 #define RTC_LP_TIMER_COMPARE_INT_MASK NRF_RTC_INT_COMPARE0_MASK @@ -59,8 +60,8 @@ #define RTC_SYNC_COMPARE_EVENT NRF_RTC_EVENT_COMPARE_1 #define RTC_SYNC_COMPARE_EVENT_MASK RTC_EVTEN_COMPARE1_Msk -#define US_PER_OVERFLOW (512UL * NRF_802154_US_PER_S) ///< Time that has passed between overflow events. On full RTC speed, it occurs every 512 s. -#define MIN_RTC_COMPARE_EVENT_DT (2 * NRF_802154_US_PER_TICK) ///< Minimum time delta from now before RTC compare event is guaranteed to fire. +#define US_PER_OVERFLOW (512UL * NRF_802154_SL_US_PER_S) ///< Time that has passed between overflow events. On full RTC speed, it occurs every 512 s. +#define MIN_RTC_COMPARE_EVENT_DT (2 * NRF_802154_SL_US_PER_TICK) ///< Minimum time delta from now before RTC compare event is guaranteed to fire. #define EPOCH_32BIT_US (1ULL << 32) #define EPOCH_FROM_TIME(time) ((time) & ((uint64_t)UINT32_MAX << 32)) @@ -97,6 +98,9 @@ static volatile uint8_t m_mutex; ///< Mutex for write access t static volatile bool m_clock_ready; ///< Information that LFCLK is ready. static volatile bool m_shall_fire_immediately; ///< Information if timer should fire immediately. +/** @brief Forward declaration of RTC interrupt handler. */ +static void rtc_irq_handler(void); + static uint32_t overflow_counter_get(void); /** @brief Non-blocking mutex for mutual write access to @ref m_offset_counter variable. @@ -157,7 +161,7 @@ static inline bool shall_strike(uint64_t now) */ static inline uint64_t time_to_ticks(uint64_t time) { - return NRF_802154_US_TO_RTC_TICKS(time); + return NRF_802154_SL_US_TO_RTC_TICKS(time); } /** @brief Convert RTC ticks to time in [us]. @@ -168,7 +172,7 @@ static inline uint64_t time_to_ticks(uint64_t time) */ static inline uint64_t ticks_to_time(uint64_t ticks) { - return NRF_802154_RTC_TICKS_TO_US(ticks); + return NRF_802154_SL_RTC_TICKS_TO_US(ticks); } /** @brief Get current value of the RTC counter. @@ -244,7 +248,7 @@ static uint32_t overflow_counter_get(void) bool increasing = false; // Check if interrupt was handled already. - if (nrf_rtc_event_pending(NRF_802154_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) + if (nrf_rtc_event_check(NRF_802154_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) { m_offset_counter++; increasing = true; @@ -279,8 +283,8 @@ static uint32_t overflow_counter_get(void) else { // Failed to acquire mutex. - if (nrf_rtc_event_pending(NRF_802154_RTC_INSTANCE, - NRF_RTC_EVENT_OVERFLOW) || (m_offset_counter & 0x01)) + if (nrf_rtc_event_check(NRF_802154_RTC_INSTANCE, + NRF_RTC_EVENT_OVERFLOW) || (m_offset_counter & 0x01)) { // Lower priority context is currently incrementing m_offset_counter variable. offset = (m_offset_counter + 2) / 2; @@ -391,44 +395,6 @@ static void timer_sync_start_at(uint32_t t0, uint32_t dt, const uint64_t * p_now nrf_rtc_int_enable(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].int_mask); } -static void rtc_irq_handler(void) -{ - // Handle overflow. - if (nrf_rtc_event_pending(NRF_802154_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) - { - // Disable OVERFLOW interrupt to prevent lock-up in interrupt context while mutex is locked from lower priority context - // and OVERFLOW event flag is stil up. - // OVERFLOW interrupt will be re-enabled when mutex is released - either from this handler, or from lower priority context, - // that locked the mutex. - nrf_rtc_int_disable(NRF_802154_RTC_INSTANCE, NRF_RTC_INT_OVERFLOW_MASK); - - // Handle OVERFLOW event by reading current value of overflow counter. - (void)overflow_counter_get(); - } - - // Handle compare match. - if (m_shall_fire_immediately) - { - m_shall_fire_immediately = false; - handle_compare_match(true); - } - - if (nrf_rtc_int_is_enabled(NRF_802154_RTC_INSTANCE, m_cmp_ch[LP_TIMER_CHANNEL].int_mask) && - nrf_rtc_event_pending(NRF_802154_RTC_INSTANCE, m_cmp_ch[LP_TIMER_CHANNEL].event)) - { - handle_compare_match(false); - } - - if (nrf_rtc_int_is_enabled(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].int_mask) && - nrf_rtc_event_pending(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].event)) - { - nrf_rtc_event_clear(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].event); - nrf_rtc_event_disable(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].event_mask); - nrf_rtc_int_disable(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].int_mask); - nrf_802154_lp_timer_synchronized(); - } -} - void nrf_802154_lp_timer_init(void) { m_offset_counter = 0; @@ -445,10 +411,10 @@ void nrf_802154_lp_timer_init(void) } // Setup RTC timer. -#if !NRF_802154_IRQ_PRIORITY_ALLOWED(NRF_802154_RTC_IRQ_PRIORITY) -#error NRF_802154_RTC_IRQ_PRIORITY value out of the allowed range. +#if !NRF_802154_IRQ_PRIORITY_ALLOWED(NRF_802154_SL_RTC_IRQ_PRIORITY) +#error NRF_802154_SL_RTC_IRQ_PRIORITY value out of the allowed range. #endif - nrf_802154_irq_init(NRF_802154_RTC_IRQN, NRF_802154_RTC_IRQ_PRIORITY, rtc_irq_handler); + nrf_802154_irq_init(NRF_802154_RTC_IRQN, NRF_802154_SL_RTC_IRQ_PRIORITY, rtc_irq_handler); nrf_802154_irq_enable(NRF_802154_RTC_IRQN); nrf_rtc_prescaler_set(NRF_802154_RTC_INSTANCE, 0); @@ -512,7 +478,7 @@ uint32_t nrf_802154_lp_timer_time_get(void) uint32_t nrf_802154_lp_timer_granularity_get(void) { - return NRF_802154_US_PER_TICK; + return NRF_802154_SL_US_PER_TICK; } void nrf_802154_lp_timer_start(uint32_t t0, uint32_t dt) @@ -544,7 +510,7 @@ void nrf_802154_lp_timer_start(uint32_t t0, uint32_t dt) bool nrf_802154_lp_timer_is_running(void) { - return nrf_rtc_int_is_enabled(NRF_802154_RTC_INSTANCE, m_cmp_ch[LP_TIMER_CHANNEL].int_mask); + return nrf_rtc_int_enable_check(NRF_802154_RTC_INSTANCE, m_cmp_ch[LP_TIMER_CHANNEL].int_mask); } void nrf_802154_lp_timer_stop(void) @@ -586,8 +552,8 @@ void nrf_802154_lp_timer_sync_stop(void) uint32_t nrf_802154_lp_timer_sync_event_get(void) { - return (uint32_t)nrf_rtc_event_address_get(NRF_802154_RTC_INSTANCE, - m_cmp_ch[SYNC_CHANNEL].event); + return nrf_rtc_event_address_get(NRF_802154_RTC_INSTANCE, + m_cmp_ch[SYNC_CHANNEL].event); } uint32_t nrf_802154_lp_timer_sync_time_get(void) @@ -600,6 +566,56 @@ void nrf_802154_clock_lfclk_ready(void) m_clock_ready = true; } +static void rtc_irq_handler(void) +{ + // Handle overflow. + if (nrf_rtc_event_check(NRF_802154_RTC_INSTANCE, NRF_RTC_EVENT_OVERFLOW)) + { + // Disable OVERFLOW interrupt to prevent lock-up in interrupt context while mutex is locked from lower priority context + // and OVERFLOW event flag is stil up. + // OVERFLOW interrupt will be re-enabled when mutex is released - either from this handler, or from lower priority context, + // that locked the mutex. + nrf_rtc_int_disable(NRF_802154_RTC_INSTANCE, NRF_RTC_INT_OVERFLOW_MASK); + + // Handle OVERFLOW event by reading current value of overflow counter. + (void)overflow_counter_get(); + } + + // Handle compare match. + if (m_shall_fire_immediately) + { + m_shall_fire_immediately = false; + handle_compare_match(true); + } + + if (nrf_rtc_int_enable_check(NRF_802154_RTC_INSTANCE, m_cmp_ch[LP_TIMER_CHANNEL].int_mask) && + nrf_rtc_event_check(NRF_802154_RTC_INSTANCE, m_cmp_ch[LP_TIMER_CHANNEL].event)) + { + handle_compare_match(false); + } + + if (nrf_rtc_int_enable_check(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].int_mask) && + nrf_rtc_event_check(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].event)) + { + // Clear event unconditionally + nrf_rtc_event_clear(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].event); + + // According to the RTC documentation, it might happen that: + // 'If the COUNTER is N and the current CC register value is N+1 or N+2 when a new CC value + // is written, a match may trigger on the previous CC value before the new value takes effect.` + // Therefore, it is possible that RTC->EVENT_COMPARE fires for an already outdated value of + // the CC register. If that's the case, the updated target time is larger than current time. + // Ignore the interrupt if that happens. + // Also, since both operands are uint64_t, there's no need to handle their overflow here. + if (curr_time_get() >= m_target_times[SYNC_CHANNEL]) + { + nrf_rtc_event_disable(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].event_mask); + nrf_rtc_int_disable(NRF_802154_RTC_INSTANCE, m_cmp_ch[SYNC_CHANNEL].int_mask); + nrf_802154_lp_timer_synchronized(); + } + } +} + void NRF_802154_RTC_IRQ_HANDLER(void) { rtc_irq_handler(); diff --git a/nrf_802154_sl/platform/lp_timer/nrf_802154_lp_timer_none.c b/nrf_802154_sl/platform/lp_timer/nrf_802154_lp_timer_none.c new file mode 100644 index 0000000..c1fc2ce --- /dev/null +++ b/nrf_802154_sl/platform/lp_timer/nrf_802154_lp_timer_none.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements the nrf 802.15.4 timer abstraction in case timer is not used. + * + * This timer abstraction should be used only when none of driver features that use timer is enabled. + * + */ + +#include "nrf_802154_lp_timer.h" + +void nrf_802154_lp_timer_init(void) +{ + // Intentionally empty +} + +void nrf_802154_lp_timer_deinit(void) +{ + // Intentionally empty +} + +void nrf_802154_lp_timer_critical_section_enter(void) +{ + // Intentionally empty +} + +void nrf_802154_lp_timer_critical_section_exit(void) +{ + // Intentionally empty +} + +// Other functions from LP timer API are intentionally not implemented to detect build configuration +// problems compile-time. diff --git a/src/fal/nrf_802154_fal.c b/src/fal/nrf_802154_fal.c index efed336..ab176b1 100644 --- a/src/fal/nrf_802154_fal.c +++ b/src/fal/nrf_802154_fal.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/fal/nrf_802154_fal.h b/src/fal/nrf_802154_fal.h index bbd9e5f..c5a6f99 100644 --- a/src/fal/nrf_802154_fal.h +++ b/src/fal/nrf_802154_fal.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/fem/none/nrf_fem_config.h b/src/fem/none/nrf_fem_config.h deleted file mode 100644 index e8daf6c..0000000 --- a/src/fem/none/nrf_fem_config.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef NRF_FEM_CONFIG_H_ -#define NRF_FEM_CONFIG_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configuration parameters for pins that enable or disable (or both) either Power Amplifier (PA) or Low Noise Amplifier (LNA). - */ -typedef struct -{ - -} nrf_fem_gpiote_pin_config_t; - -/** - * @brief Configuration parameters for the PA/LNA interface. - */ -typedef struct -{ - -} nrf_fem_interface_config_t; - -#ifdef __cplusplus -} -#endif - -#endif /* NRF_FEM_CONFIG_H_ */ diff --git a/src/fem/nrf_fem_control_config.h b/src/fem/nrf_fem_control_config.h deleted file mode 100644 index 6c93bba..0000000 --- a/src/fem/nrf_fem_control_config.h +++ /dev/null @@ -1,107 +0,0 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef NRF_FEM_CONTROL_CONFIG_H_ -#define NRF_FEM_CONTROL_CONFIG_H_ - -#if ENABLE_FEM -#include "nrf_fem_config.h" -#endif // ENABLE_FEM - -#include -#include - -#include "nrf_error.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @section Configuration - */ - -#if ENABLE_FEM - -/** - * @brief Configures the PA and LNA device interface. - * - * This function sets device interface parameters for the PA/LNA module. - * The module can then be used to control a power amplifier or a low noise amplifier (or both) through the given interface and resources. - * - * The function also sets the PPI and GPIOTE channels to be configured for the PA/LNA interface. - * - * @param[in] p_config Pointer to the interface parameters for the PA/LNA device. - * - * @retval ::NRF_SUCCESS PA/LNA control successfully configured. - * @retval ::NRF_ERROR_NOT_SUPPORTED PA/LNA is not available. - * - */ -int32_t nrf_fem_interface_configuration_set(nrf_fem_interface_config_t const * const p_config); - -/** - * @brief Retrieves the configuration of PA and LNA device interface. - * - * This function gets device interface parameters for the PA/LNA module. - * The module can then be used to control a power amplifier or a low noise amplifier (or both) through the given interface and resources. - * - * - * @param[in] p_config Pointer to the interface parameters for the PA/LNA device to be populated. - * - * @retval ::NRF_SUCCESS PA/LNA control successfully configured. - * @retval ::NRF_ERROR_NOT_SUPPORTED PA/LNA is not available. - * - */ -int32_t nrf_fem_interface_configuration_get(nrf_fem_interface_config_t * p_config); - -#else // ENABLE_FEM - -typedef void nrf_fem_interface_config_t; - -static inline int32_t nrf_fem_interface_configuration_set( - nrf_fem_interface_config_t const * const p_config) -{ - (void)p_config; - return NRF_ERROR_NOT_SUPPORTED; -} - -static inline int32_t nrf_fem_interface_configuration_get(nrf_fem_interface_config_t * p_config) -{ - (void)p_config; - return NRF_ERROR_NOT_SUPPORTED; -} - -#endif // ENABLE_FEM - -#ifdef __cplusplus -} -#endif - -#endif /* NRF_FEM_CONTROL_CONFIG_H_ */ diff --git a/src/fem/nrf_fem_protocol_legacy_api.h b/src/fem/nrf_fem_protocol_legacy_api.h deleted file mode 100644 index 0411577..0000000 --- a/src/fem/nrf_fem_protocol_legacy_api.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include - -/** - * @brief Configuration parameters for PA and LNA. - */ -typedef struct -{ - uint8_t enable : 1; /**< Enable toggling for this amplifier. */ - uint8_t active_high : 1; /**< Set the pin to be active high. */ - uint8_t gpio_pin : 6; /**< The GPIO pin to be toggled for this amplifier. */ -} nrf_fem_control_pa_lna_cfg_t; - -/** - * @brief PA and LNA GPIO toggle configuration. - * - * This option configures the nRF 802.15.4 radio driver to toggle pins when the radio - * is active and ready for use with a Power Amplifier (PA) or a Low Noise Amplifier (LNA), or both. - * - * Pins can be toggled by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided - * by the application and are to be regarded as reserved for as long as there is no PA/LNA toggling enabled. - * - * @note Avoid changing this configuration while the radio is in use, as this can lead to undefined consequences. - * - */ -typedef struct -{ - nrf_fem_control_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration. */ - nrf_fem_control_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration. */ - uint8_t pa_gpiote_ch_id; /**< GPIOTE channel used for Power Amplifier pin toggling. */ - uint8_t lna_gpiote_ch_id; /**< GPIOTE channel used for Low Noise Amplifier pin toggling. */ - uint8_t ppi_ch_id_set; /**< PPI channel used for radio Power Amplifier and Low Noise Amplifier pins setting. */ - uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing. */ -} nrf_fem_control_cfg_t; diff --git a/src/fem/simple_gpio/nrf_fem_config.h b/src/fem/simple_gpio/nrf_fem_config.h deleted file mode 100644 index aa16f06..0000000 --- a/src/fem/simple_gpio/nrf_fem_config.h +++ /dev/null @@ -1,127 +0,0 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef NRF_FEM_CONFIG_H_ -#define NRF_FEM_CONFIG_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configuration parameters for pins that enable or disable (or both) either Power Amplifier (PA) or Low Noise Amplifier (LNA). - */ -typedef struct -{ - bool enable; /* Enable toggling for this pin. */ - bool active_high; /* If true, the pin will be active high. Otherwise, the pin will be active low. */ - uint8_t gpio_pin; /* GPIO pin number for the pin. */ - uint8_t gpiote_ch_id; /* GPIOTE channel to be used for toggling pins. */ -} nrf_fem_gpiote_pin_config_t; - -/** - * @brief Configuration parameters for the PA/LNA interface. - */ -typedef struct -{ - struct - { - uint32_t pa_time_gap_us; /* Time between the activation of the PA pin and the start of the radio transmission. */ - uint32_t lna_time_gap_us; /* Time between the activation of the LNA pin and the start of the radio reception. */ - int8_t pa_gain_db; /* Configurable PA gain. Ignored if the amplifier is not supporting this feature. */ - int8_t lna_gain_db; /* Configurable LNA gain. Ignored if the amplifier is not supporting this feature. */ - } fem_config; - - nrf_fem_gpiote_pin_config_t pa_pin_config; /* Power Amplifier pin configuration. */ - nrf_fem_gpiote_pin_config_t lna_pin_config; /* Low Noise Amplifier pin configuration. */ - - uint8_t ppi_ch_id_set; /* PPI channel to be used for setting pins. */ - uint8_t ppi_ch_id_clr; /* PPI channel to be used for clearing pins. */ -} nrf_fem_interface_config_t; - -/** - * @section Timings. - */ - -/** Time in microseconds when PA GPIO is activated before the radio is ready for transmission. */ -#define NRF_FEM_PA_TIME_IN_ADVANCE_US 23 - -/** Time in microseconds when LNA GPIO is activated before the radio is ready for reception. */ -#define NRF_FEM_LNA_TIME_IN_ADVANCE_US 5 - -#ifdef NRF52811_XXAA -/** Default Power Amplifier pin. */ -#define NRF_FEM_CONTROL_DEFAULT_PA_PIN 19 - -/** Default Low Noise Amplifier pin. */ -#define NRF_FEM_CONTROL_DEFAULT_LNA_PIN 20 - -#else - -/** Default Power Amplifier pin. */ -#define NRF_FEM_CONTROL_DEFAULT_PA_PIN 15 - -/** Default Low Noise Amplifier pin. */ -#define NRF_FEM_CONTROL_DEFAULT_LNA_PIN 16 -#endif - -/** Default PPI channel for pin setting. */ -#define NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL 15 - -/** Default PPI channel for pin clearing. */ -#define NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL 16 - -/** Default GPIOTE channel for FEM control. */ -#define NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL 6 - -/** Default GPIOTE channel for FEM control. */ -#define NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL 7 - -/** Mask of GPIO pins used for FEM control. */ -#define NRF_802154_FEM_PINS_USED_MASK ((1 << NRF_FEM_CONTROL_DEFAULT_PA_PIN) | \ - (1 << NRF_FEM_CONTROL_DEFAULT_LNA_PIN)) - -/** Mask of PPI channels used for FEM control. */ -#define NRF_802154_FEM_PPI_CHANNELS_USED_MASK ((1 << NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL) | \ - (1 << NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL)) - -/** Mask of GPIOTE channels used for FEM control. */ -#define NRF_802154_FEM_GPIOTE_CHANNELS_USED_MASK ( \ - (1 << NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL) | \ - (1 << NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL)) - -#ifdef __cplusplus -} -#endif - -#endif /* NRF_FEM_CONFIG_H_ */ diff --git a/src/fem/simple_gpio/nrf_fem_simple_gpio.c b/src/fem/simple_gpio/nrf_fem_simple_gpio.c deleted file mode 100644 index 62ba56c..0000000 --- a/src/fem/simple_gpio/nrf_fem_simple_gpio.c +++ /dev/null @@ -1,470 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements common function for Front End Module control of the nRF 802.15.4 radio driver. - * - */ -#include "nrf_fem_protocol_api.h" - -#include -#include -#include - -#include "compiler_abstraction.h" -#include "nrf_802154_config.h" -#include "nrf.h" -#include "nrf_error.h" -#include "nrf_gpio.h" -#include "nrf_gpiote.h" -#include "nrf_ppi.h" -#include "nrf_radio.h" -#include "nrf_timer.h" - -#if ENABLE_FEM - -#define PPI_INVALID_CHANNEL 0xFF /**< Default value for the PPI holder variable. */ - -static nrf_fem_interface_config_t m_nrf_fem_interface_config = /**< FEM controller configuration. */ -{ - .fem_config = - { - .pa_time_gap_us = NRF_FEM_PA_TIME_IN_ADVANCE_US, - .lna_time_gap_us = NRF_FEM_LNA_TIME_IN_ADVANCE_US - }, - .pa_pin_config = - { - .enable = 1, - .active_high = 1, - .gpio_pin = NRF_FEM_CONTROL_DEFAULT_PA_PIN, - .gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL - }, - .lna_pin_config = - { - .enable = 1, - .active_high = 1, - .gpio_pin = NRF_FEM_CONTROL_DEFAULT_LNA_PIN, - .gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL - }, - .ppi_ch_id_set = NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL, - .ppi_ch_id_clr = NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL -}; -static uint8_t m_ppi_channel_ext = PPI_INVALID_CHANNEL; /**< PPI channel provided by the `override_ppi = true` functionality. */ - -/** Map the mask bits with the Compare Channels. */ -static uint32_t get_first_available_compare_channel(uint8_t mask) -{ - if (mask & (1 << 0)) - return NRF_TIMER_CC_CHANNEL0; - if (mask & (1 << 1)) - return NRF_TIMER_CC_CHANNEL1; - if (mask & (1 << 2)) - return NRF_TIMER_CC_CHANNEL2; - if (mask & (1 << 3)) - return NRF_TIMER_CC_CHANNEL3; - assert(false); - return 0; -} - -/** Configure GPIOTE module. */ -static void gpiote_configure(void) -{ - if (m_nrf_fem_interface_config.pa_pin_config.enable) - { - nrf_gpiote_task_configure(m_nrf_fem_interface_config.pa_pin_config.gpiote_ch_id, - m_nrf_fem_interface_config.pa_pin_config.gpio_pin, - (nrf_gpiote_polarity_t)GPIOTE_CONFIG_POLARITY_None, - (nrf_gpiote_outinit_t) !m_nrf_fem_interface_config.pa_pin_config.active_high); - - nrf_gpiote_task_enable(m_nrf_fem_interface_config.pa_pin_config.gpiote_ch_id); - } - - if (m_nrf_fem_interface_config.lna_pin_config.enable) - { - nrf_gpiote_task_configure(m_nrf_fem_interface_config.lna_pin_config.gpiote_ch_id, - m_nrf_fem_interface_config.lna_pin_config.gpio_pin, - (nrf_gpiote_polarity_t)GPIOTE_CONFIG_POLARITY_None, - (nrf_gpiote_outinit_t) !m_nrf_fem_interface_config.lna_pin_config.active_high); - - nrf_gpiote_task_enable(m_nrf_fem_interface_config.lna_pin_config.gpiote_ch_id); - } -} - -/** Configure the event with the provided values. */ -static int32_t event_configuration_set(const nrf_802154_fal_event_t * const p_event, - nrf_fem_gpiote_pin_config_t * p_pin_config, - bool activate, - uint32_t time_delay) -{ - uint32_t task_addr; - uint8_t ppi_ch; - - assert(p_event); - assert(p_pin_config); - - if (p_event->override_ppi) - { - assert(p_event->ppi_ch_id != PPI_INVALID_CHANNEL); - if (m_ppi_channel_ext == PPI_INVALID_CHANNEL) - { - /* External PPI channel placeholder is free. */ - m_ppi_channel_ext = ppi_ch = p_event->ppi_ch_id; - } - else if ((m_ppi_channel_ext == p_event->ppi_ch_id) && - (!NRF_PPI->FORK[(uint32_t)m_ppi_channel_ext].TEP)) - { - /* PPI is equal to the already set, but the one set has a free fork endpoint. */ - ppi_ch = p_event->ppi_ch_id; - } - else - { - return NRF_ERROR_INVALID_STATE; - } - } - else - { - ppi_ch = - activate ? m_nrf_fem_interface_config.ppi_ch_id_set : m_nrf_fem_interface_config. - ppi_ch_id_clr; - } - - if (p_pin_config->active_high ^ activate) - { - task_addr = (uint32_t)(&NRF_GPIOTE->TASKS_CLR[p_pin_config->gpiote_ch_id]); - } - else - { - task_addr = (uint32_t)(&NRF_GPIOTE->TASKS_SET[p_pin_config->gpiote_ch_id]); - } - - switch (p_event->type) - { - case NRF_802154_FAL_EVENT_TYPE_GENERIC: - { - if (NRF_PPI->CH[(uint32_t)ppi_ch].TEP) - { - nrf_ppi_fork_endpoint_setup((nrf_ppi_channel_t)ppi_ch, task_addr); - } - else - { - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)ppi_ch, - p_event->event.generic.register_address, - task_addr); - } - - nrf_ppi_channel_enable((nrf_ppi_channel_t)ppi_ch); - } - break; - - case NRF_802154_FAL_EVENT_TYPE_TIMER: - { - assert(p_event->event.timer.compare_channel_mask); - - uint32_t compare_channel = get_first_available_compare_channel( - p_event->event.timer.compare_channel_mask); - - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)ppi_ch, - (uint32_t)(&(p_event->event.timer.p_timer_instance-> - EVENTS_COMPARE[compare_channel])), - task_addr); - nrf_ppi_channel_enable((nrf_ppi_channel_t)ppi_ch); - - nrf_timer_cc_write(p_event->event.timer.p_timer_instance, - (nrf_timer_cc_channel_t)compare_channel, - p_event->event.timer.counter_value - time_delay); - } - break; - - default: - assert(false); - break; - } - - return NRF_SUCCESS; -} - -/** Deconfigure the event with the provided values. */ -static int32_t event_configuration_clear(const nrf_802154_fal_event_t * const p_event, - bool activate) -{ - uint8_t ppi_ch; - - assert(p_event); - - if (p_event->override_ppi) - { - ppi_ch = p_event->ppi_ch_id; - } - else - { - ppi_ch = - activate ? m_nrf_fem_interface_config.ppi_ch_id_set : m_nrf_fem_interface_config. - ppi_ch_id_clr; - } - - nrf_ppi_channel_disable((nrf_ppi_channel_t)ppi_ch); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)ppi_ch, 0, 0); - nrf_ppi_fork_endpoint_setup((nrf_ppi_channel_t)ppi_ch, 0); - - switch (p_event->type) - { - case NRF_802154_FAL_EVENT_TYPE_GENERIC: - break; - - case NRF_802154_FAL_EVENT_TYPE_TIMER: - break; - - default: - assert(false); - break; - } - - return NRF_SUCCESS; -} - -int32_t nrf_802154_fal_pa_configuration_set(const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - int32_t ret_code; - - if (!m_nrf_fem_interface_config.pa_pin_config.enable) - { - return NRF_ERROR_FORBIDDEN; - } - - if (p_activate_event) - { - ret_code = event_configuration_set(p_activate_event, - &m_nrf_fem_interface_config.pa_pin_config, - true, - m_nrf_fem_interface_config.fem_config.pa_time_gap_us); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - if (p_deactivate_event) - { - ret_code = event_configuration_set(p_deactivate_event, - &m_nrf_fem_interface_config.pa_pin_config, - false, - m_nrf_fem_interface_config.fem_config.pa_time_gap_us); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - return NRF_SUCCESS; -} - -int32_t nrf_802154_fal_lna_configuration_set(const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - int32_t ret_code; - - if (!m_nrf_fem_interface_config.lna_pin_config.enable) - { - return NRF_ERROR_FORBIDDEN; - } - - if (p_activate_event) - { - ret_code = event_configuration_set(p_activate_event, - &m_nrf_fem_interface_config.lna_pin_config, - true, - m_nrf_fem_interface_config.fem_config.lna_time_gap_us); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - if (p_deactivate_event) - { - ret_code = event_configuration_set(p_deactivate_event, - &m_nrf_fem_interface_config.lna_pin_config, - false, - m_nrf_fem_interface_config.fem_config.lna_time_gap_us); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - return NRF_SUCCESS; -} - -int32_t nrf_802154_fal_pa_configuration_clear(const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - int32_t ret_code; - - if (!m_nrf_fem_interface_config.pa_pin_config.enable) - { - return NRF_ERROR_FORBIDDEN; - } - - if (p_activate_event) - { - ret_code = event_configuration_clear(p_activate_event, true); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - if (p_deactivate_event) - { - ret_code = event_configuration_clear(p_deactivate_event, false); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - return NRF_SUCCESS; -} - -int32_t nrf_802154_fal_lna_configuration_clear( - const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - int32_t ret_code; - - if (!m_nrf_fem_interface_config.lna_pin_config.enable) - { - return NRF_ERROR_FORBIDDEN; - } - - if (p_activate_event) - { - ret_code = event_configuration_clear(p_activate_event, true); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - if (p_deactivate_event) - { - ret_code = event_configuration_clear(p_deactivate_event, false); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - return NRF_SUCCESS; -} - -void nrf_802154_fal_deactivate_now(nrf_fal_functionality_t type) -{ - if (m_nrf_fem_interface_config.pa_pin_config.enable && (type & NRF_802154_FAL_PA)) - { - if (m_nrf_fem_interface_config.pa_pin_config.active_high) - { - nrf_gpiote_task_force(m_nrf_fem_interface_config.pa_pin_config.gpiote_ch_id, - NRF_GPIOTE_INITIAL_VALUE_LOW); - } - else - { - nrf_gpiote_task_force(m_nrf_fem_interface_config.pa_pin_config.gpiote_ch_id, - NRF_GPIOTE_INITIAL_VALUE_HIGH); - } - } - - if (m_nrf_fem_interface_config.lna_pin_config.enable && (type & NRF_802154_FAL_LNA)) - { - if (m_nrf_fem_interface_config.lna_pin_config.active_high) - { - nrf_gpiote_task_force(m_nrf_fem_interface_config.lna_pin_config.gpiote_ch_id, - NRF_GPIOTE_INITIAL_VALUE_LOW); - } - else - { - nrf_gpiote_task_force(m_nrf_fem_interface_config.lna_pin_config.gpiote_ch_id, - NRF_GPIOTE_INITIAL_VALUE_HIGH); - } - } -} - -int32_t nrf_fem_interface_configuration_set(nrf_fem_interface_config_t const * const p_config) -{ - m_nrf_fem_interface_config = *p_config; - - if (m_nrf_fem_interface_config.pa_pin_config.enable || - m_nrf_fem_interface_config.lna_pin_config.enable) - { - gpiote_configure(); - } - - return NRF_SUCCESS; -} - -int32_t nrf_fem_interface_configuration_get(nrf_fem_interface_config_t * p_config) -{ - *p_config = m_nrf_fem_interface_config; - - return NRF_SUCCESS; -} - -void nrf_802154_fal_cleanup(void) -{ - nrf_ppi_channel_disable((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_set); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_set, 0, - 0); - nrf_ppi_fork_endpoint_setup((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_set, 0); - nrf_ppi_channel_disable((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_clr); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_clr, 0, - 0); - nrf_ppi_fork_endpoint_setup((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_clr, 0); - if (m_ppi_channel_ext != PPI_INVALID_CHANNEL) - { - nrf_ppi_channel_disable((nrf_ppi_channel_t)m_ppi_channel_ext); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)m_ppi_channel_ext, 0, 0); - nrf_ppi_fork_endpoint_setup((nrf_ppi_channel_t)m_ppi_channel_ext, 0); - m_ppi_channel_ext = PPI_INVALID_CHANNEL; - } -} - -bool nrf_fem_prepare_powerdown(NRF_TIMER_Type * p_instance, - uint32_t compare_channel, - nrf_ppi_channel_t ppi_id) -{ - (void)p_instance; - (void)compare_channel; - (void)ppi_id; - return false; -} - -#endif // ENABLE_FEM diff --git a/src/fem/three_pin_gpio/nrf_fem_config.h b/src/fem/three_pin_gpio/nrf_fem_config.h deleted file mode 100644 index d20e2d3..0000000 --- a/src/fem/three_pin_gpio/nrf_fem_config.h +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef NRF_FEM_CONFIG_H_ -#define NRF_FEM_CONFIG_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configuration parameters for pins that enable or disable (or both) either Power Amplifier (PA) or Low Noise Amplifier (LNA). - */ -typedef struct -{ - bool enable; /* Enable toggling for this pin. */ - bool active_high; /* If true, the pin will be active high. Otherwise, the pin will be active low. */ - uint8_t gpio_pin; /* GPIO pin number for the pin. */ - uint8_t gpiote_ch_id; /* GPIOTE channel to be used for toggling pins. */ -} nrf_fem_gpiote_pin_config_t; - -/** - * @brief Configuration parameters for the PA/LNA interface. - */ -typedef struct -{ - struct - { - uint32_t pa_time_gap_us; /* Time between the activation of the PA pin and the start of the radio transmission. */ - uint32_t lna_time_gap_us; /* Time between the activation of the LNA pin and the start of the radio reception. */ - uint32_t pdn_settle_us; /* The time between activating the PDN and asserting the PA/LNA pin. */ - uint32_t trx_hold_us; /* The time between deasserting the PA/LNA pin and deactivating PDN. */ - int8_t pa_gain_db; /* Configurable PA gain. Ignored if the amplifier is not supporting this feature. */ - int8_t lna_gain_db; /* Configurable LNA gain. Ignored if the amplifier is not supporting this feature. */ - } fem_config; - - nrf_fem_gpiote_pin_config_t pa_pin_config; /* Power Amplifier pin configuration. */ - nrf_fem_gpiote_pin_config_t lna_pin_config; /* Low Noise Amplifier pin configuration. */ - nrf_fem_gpiote_pin_config_t pdn_pin_config; /* Power Down pin configuration. */ - - uint8_t ppi_ch_id_set; /* PPI channel to be used for setting pins. */ - uint8_t ppi_ch_id_clr; /* PPI channel to be used for clearing pins. */ - uint8_t ppi_ch_id_pdn; /* PPI channel to handle PDN pin. */ -} nrf_fem_interface_config_t; - -/** - * @section Timings. - */ - -/** Time in microseconds when PA GPIO is activated before the radio is ready for transmission. */ -#define NRF_FEM_PA_TIME_IN_ADVANCE_US 13 - -/** Time in microseconds when LNA GPIO is activated before the radio is ready for reception. */ -#define NRF_FEM_LNA_TIME_IN_ADVANCE_US 13 - -/** The time between activating the PDN and asserting the RX_EN/TX_EN. */ -#define NRF_FEM_PDN_SETTLE_US 18 - -/** The time between deasserting the RX_EN/TX_EN and deactivating PDN. */ -#define NRF_FEM_TRX_HOLD_US 5 - -#ifdef NRF52811_XXAA -/** Default Power Amplifier pin. */ -#define NRF_FEM_CONTROL_DEFAULT_PA_PIN 19 - -/** Default Low Noise Amplifier pin. */ -#define NRF_FEM_CONTROL_DEFAULT_LNA_PIN 20 - -#else - -/** Default Power Amplifier pin. */ -#define NRF_FEM_CONTROL_DEFAULT_PA_PIN 15 - -/** Default Low Noise Amplifier pin. */ -#define NRF_FEM_CONTROL_DEFAULT_LNA_PIN 16 -#endif - -/** Default Eagle PDN pin. */ -#define NRF_FEM_CONTROL_DEFAULT_PDN_PIN 13 - -/** Default PPI channel for pin setting. */ -#define NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL 15 - -/** Default PPI channel for pin clearing. */ -#define NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL 16 - -/** Default PPI channel for PDN pin handling. */ -#define NRF_FEM_CONTROL_DEFAULT_PDN_PPI_CHANNEL 5 - -/** Default GPIOTE channel for PDN control. */ -#define NRF_FEM_CONTROL_DEFAULT_PDN_GPIOTE_CHANNEL 5 - -/** Default GPIOTE channel for LNA control. */ -#define NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL 6 - -/** Default GPIOTE channel for PA control. */ -#define NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL 7 - -/** Mask of GPIO pins used for FEM control. */ -#define NRF_802154_FEM_PINS_USED_MASK ((1 << NRF_FEM_CONTROL_DEFAULT_PA_PIN) | \ - (1 << NRF_FEM_CONTROL_DEFAULT_LNA_PIN) | \ - (1 << NRF_FEM_CONTROL_DEFAULT_PDN_PIN)) - -/** Mask of PPI channels used for FEM control. */ -#define NRF_802154_FEM_PPI_CHANNELS_USED_MASK ((1 << NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL) | \ - (1 << NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL) | \ - (1 << NRF_FEM_CONTROL_DEFAULT_PDN_PPI_CHANNEL)) - -/** Mask of GPIOTE channels used for FEM control. */ -#define NRF_802154_FEM_GPIOTE_CHANNELS_USED_MASK ( \ - (1 << NRF_FEM_CONTROL_DEFAULT_PDN_GPIOTE_CHANNEL) | \ - (1 << NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL) | \ - (1 << NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL)) - -#ifdef __cplusplus -} -#endif - -#endif /* NRF_FEM_CONFIG_H_ */ diff --git a/src/fem/three_pin_gpio/nrf_fem_three_pin_gpio.c b/src/fem/three_pin_gpio/nrf_fem_three_pin_gpio.c deleted file mode 100644 index 68bad9d..0000000 --- a/src/fem/three_pin_gpio/nrf_fem_three_pin_gpio.c +++ /dev/null @@ -1,575 +0,0 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements common function for Front End Module control of the nRF 802.15.4 radio driver. - * - */ -#include "nrf_fem_protocol_api.h" - -#include -#include -#include - -#include "compiler_abstraction.h" -#include "nrf_802154_config.h" -#include "nrf.h" -#include "nrf_error.h" -#include "nrf_gpio.h" -#include "nrf_gpiote.h" -#include "nrf_ppi.h" -#include "nrf_radio.h" -#include "nrf_timer.h" - -#if ENABLE_FEM - -#define PPI_INVALID_CHANNEL 0xFF /**< Default value for the PPI holder variable. */ - -static nrf_fem_interface_config_t m_nrf_fem_interface_config = /**< FEM controller configuration. */ -{ - .fem_config = - { - .pa_time_gap_us = NRF_FEM_PA_TIME_IN_ADVANCE_US, - .lna_time_gap_us = NRF_FEM_LNA_TIME_IN_ADVANCE_US, - .pdn_settle_us = NRF_FEM_PDN_SETTLE_US, - .trx_hold_us = NRF_FEM_TRX_HOLD_US, - }, - .pa_pin_config = - { - .enable = 1, - .active_high = 1, - .gpio_pin = NRF_FEM_CONTROL_DEFAULT_PA_PIN, - .gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL - }, - .lna_pin_config = - { - .enable = 1, - .active_high = 1, - .gpio_pin = NRF_FEM_CONTROL_DEFAULT_LNA_PIN, - .gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL - }, - .pdn_pin_config = - { - .enable = 1, - .gpio_pin = NRF_FEM_CONTROL_DEFAULT_PDN_PIN, - .active_high = 1, - .gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_PDN_GPIOTE_CHANNEL - }, - .ppi_ch_id_set = NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL, - .ppi_ch_id_clr = NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL, - .ppi_ch_id_pdn = NRF_FEM_CONTROL_DEFAULT_PDN_PPI_CHANNEL -}; -static uint8_t m_ppi_channel_ext = PPI_INVALID_CHANNEL; /**< PPI channel provided by the `override_ppi = true` functionality. */ - -/** Map the mask bits with the Compare Channels. */ -static uint32_t get_available_compare_channel(uint8_t mask, uint32_t number) -{ - uint32_t i; - - for (i = 0; i < 4; i++) - { - if (mask & (1 << i)) - { - if (number == 0) - { - break; - } - else - { - number--; - } - } - } - - if (i == 0) - return NRF_TIMER_CC_CHANNEL0; - if (i == 1) - return NRF_TIMER_CC_CHANNEL1; - if (i == 2) - return NRF_TIMER_CC_CHANNEL2; - if (i == 3) - return NRF_TIMER_CC_CHANNEL3; - assert(false); - return 0; -} - -/** Configure GPIOTE module. */ -static void gpiote_configure(void) -{ - if (m_nrf_fem_interface_config.pa_pin_config.enable) - { - nrf_gpiote_task_configure(m_nrf_fem_interface_config.pa_pin_config.gpiote_ch_id, - m_nrf_fem_interface_config.pa_pin_config.gpio_pin, - (nrf_gpiote_polarity_t)GPIOTE_CONFIG_POLARITY_None, - (nrf_gpiote_outinit_t) !m_nrf_fem_interface_config.pa_pin_config.active_high); - - nrf_gpiote_task_enable(m_nrf_fem_interface_config.pa_pin_config.gpiote_ch_id); - } - - if (m_nrf_fem_interface_config.lna_pin_config.enable) - { - nrf_gpiote_task_configure(m_nrf_fem_interface_config.lna_pin_config.gpiote_ch_id, - m_nrf_fem_interface_config.lna_pin_config.gpio_pin, - (nrf_gpiote_polarity_t)GPIOTE_CONFIG_POLARITY_None, - (nrf_gpiote_outinit_t) !m_nrf_fem_interface_config.lna_pin_config.active_high); - - nrf_gpiote_task_enable(m_nrf_fem_interface_config.lna_pin_config.gpiote_ch_id); - } - - if (m_nrf_fem_interface_config.pdn_pin_config.enable) - { - nrf_gpiote_task_configure(m_nrf_fem_interface_config.pdn_pin_config.gpiote_ch_id, - m_nrf_fem_interface_config.pdn_pin_config.gpio_pin, - (nrf_gpiote_polarity_t)GPIOTE_CONFIG_POLARITY_None, - (nrf_gpiote_outinit_t) !m_nrf_fem_interface_config.pdn_pin_config.active_high); - - nrf_gpiote_task_enable(m_nrf_fem_interface_config.pdn_pin_config.gpiote_ch_id); - } -} - -/** Configure the event with the provided values. */ -static int32_t event_configuration_set(const nrf_802154_fal_event_t * const p_event, - nrf_fem_gpiote_pin_config_t * p_pin_config, - bool activate, - uint32_t time_delay) -{ - uint32_t task_addr; - uint8_t ppi_ch; - - assert(p_event); - assert(p_pin_config); - - if (p_event->override_ppi) - { - assert(p_event->ppi_ch_id != PPI_INVALID_CHANNEL); - if (m_ppi_channel_ext == PPI_INVALID_CHANNEL) - { - /* External PPI channel placeholder is free. */ - m_ppi_channel_ext = ppi_ch = p_event->ppi_ch_id; - } - else if ((m_ppi_channel_ext == p_event->ppi_ch_id) && - (!NRF_PPI->FORK[(uint32_t)m_ppi_channel_ext].TEP)) - { - /* PPI is equal to the already set, but the one set has a free fork endpoint. */ - ppi_ch = p_event->ppi_ch_id; - } - else - { - return NRF_ERROR_INVALID_STATE; - } - } - else - { - ppi_ch = - activate ? m_nrf_fem_interface_config.ppi_ch_id_set : m_nrf_fem_interface_config. - ppi_ch_id_clr; - } - - if (p_pin_config->active_high ^ activate) - { - task_addr = (uint32_t)(&NRF_GPIOTE->TASKS_CLR[p_pin_config->gpiote_ch_id]); - } - else - { - task_addr = (uint32_t)(&NRF_GPIOTE->TASKS_SET[p_pin_config->gpiote_ch_id]); - } - - switch (p_event->type) - { - case NRF_802154_FAL_EVENT_TYPE_GENERIC: - { - if (NRF_PPI->CH[(uint32_t)ppi_ch].TEP) - { - nrf_ppi_fork_endpoint_setup((nrf_ppi_channel_t)ppi_ch, task_addr); - } - else - { - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)ppi_ch, - p_event->event.generic.register_address, - task_addr); - } - - nrf_ppi_channel_enable((nrf_ppi_channel_t)ppi_ch); - } - break; - - case NRF_802154_FAL_EVENT_TYPE_TIMER: - { - assert(p_event->event.timer.compare_channel_mask); - - uint32_t compare_channel; - uint32_t pdn_task_addr; - - /* EN pin */ - compare_channel = get_available_compare_channel( - p_event->event.timer.compare_channel_mask, - 0); - - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)ppi_ch, - (uint32_t)(&(p_event->event.timer.p_timer_instance-> - EVENTS_COMPARE[compare_channel])), - task_addr); - nrf_ppi_channel_enable((nrf_ppi_channel_t)ppi_ch); - - nrf_timer_cc_write(p_event->event.timer.p_timer_instance, - (nrf_timer_cc_channel_t)compare_channel, - p_event->event.timer.counter_value - time_delay); - - /* PDN pin */ - if (m_nrf_fem_interface_config.pdn_pin_config.active_high) - { - pdn_task_addr = - (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_interface_config.pdn_pin_config. - gpiote_ch_id]); - } - else - { - pdn_task_addr = - (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_interface_config.pdn_pin_config. - gpiote_ch_id]); - } - - compare_channel = get_available_compare_channel( - p_event->event.timer.compare_channel_mask, - 1); - - nrf_ppi_channel_endpoint_setup( - (nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_pdn, - (uint32_t)(&(p_event->event.timer.p_timer_instance-> - EVENTS_COMPARE[compare_channel])), - pdn_task_addr); - - nrf_ppi_channel_enable((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_pdn); - - nrf_timer_cc_write(p_event->event.timer.p_timer_instance, - (nrf_timer_cc_channel_t)compare_channel, - p_event->event.timer.counter_value - time_delay - - m_nrf_fem_interface_config.fem_config.pdn_settle_us); - break; - } - - default: - assert(false); - break; - } - - return NRF_SUCCESS; -} - -/** Deconfigure the event with the provided values. */ -static int32_t event_configuration_clear(const nrf_802154_fal_event_t * const p_event, - bool activate) -{ - uint8_t ppi_ch; - - assert(p_event); - - if (p_event->override_ppi) - { - ppi_ch = p_event->ppi_ch_id; - } - else - { - ppi_ch = - activate ? m_nrf_fem_interface_config.ppi_ch_id_set : m_nrf_fem_interface_config. - ppi_ch_id_clr; - } - - nrf_ppi_channel_disable((nrf_ppi_channel_t)ppi_ch); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)ppi_ch, 0, 0); - nrf_ppi_fork_endpoint_setup((nrf_ppi_channel_t)ppi_ch, 0); - - switch (p_event->type) - { - case NRF_802154_FAL_EVENT_TYPE_GENERIC: - case NRF_802154_FAL_EVENT_TYPE_TIMER: - break; - - default: - assert(false); - break; - } - - return NRF_SUCCESS; -} - -int32_t nrf_802154_fal_pa_configuration_set(const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - int32_t ret_code; - - if (!m_nrf_fem_interface_config.pa_pin_config.enable) - { - return NRF_ERROR_FORBIDDEN; - } - - if (p_activate_event) - { - ret_code = event_configuration_set(p_activate_event, - &m_nrf_fem_interface_config.pa_pin_config, - true, - m_nrf_fem_interface_config.fem_config.pa_time_gap_us); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - if (p_deactivate_event) - { - ret_code = event_configuration_set(p_deactivate_event, - &m_nrf_fem_interface_config.pa_pin_config, - false, - m_nrf_fem_interface_config.fem_config.pa_time_gap_us); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - return NRF_SUCCESS; -} - -int32_t nrf_802154_fal_lna_configuration_set(const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - int32_t ret_code; - - if (!m_nrf_fem_interface_config.lna_pin_config.enable) - { - return NRF_ERROR_FORBIDDEN; - } - - if (p_activate_event) - { - ret_code = event_configuration_set(p_activate_event, - &m_nrf_fem_interface_config.lna_pin_config, - true, - m_nrf_fem_interface_config.fem_config.lna_time_gap_us); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - if (p_deactivate_event) - { - ret_code = event_configuration_set(p_deactivate_event, - &m_nrf_fem_interface_config.lna_pin_config, - false, - m_nrf_fem_interface_config.fem_config.lna_time_gap_us); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - return NRF_SUCCESS; -} - -int32_t nrf_802154_fal_pa_configuration_clear(const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - int32_t ret_code; - - if (!m_nrf_fem_interface_config.pa_pin_config.enable) - { - return NRF_ERROR_FORBIDDEN; - } - - if (p_activate_event) - { - ret_code = event_configuration_clear(p_activate_event, true); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - if (p_deactivate_event) - { - ret_code = event_configuration_clear(p_deactivate_event, false); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - return NRF_SUCCESS; -} - -int32_t nrf_802154_fal_lna_configuration_clear( - const nrf_802154_fal_event_t * const p_activate_event, - const nrf_802154_fal_event_t * const p_deactivate_event) -{ - int32_t ret_code; - - if (!m_nrf_fem_interface_config.lna_pin_config.enable) - { - return NRF_ERROR_FORBIDDEN; - } - - if (p_activate_event) - { - ret_code = event_configuration_clear(p_activate_event, true); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - if (p_deactivate_event) - { - ret_code = event_configuration_clear(p_deactivate_event, false); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - } - - return NRF_SUCCESS; -} - -void nrf_802154_fal_deactivate_now(nrf_fal_functionality_t type) -{ - if (m_nrf_fem_interface_config.pa_pin_config.enable && (type & NRF_802154_FAL_PA)) - { - if (m_nrf_fem_interface_config.pa_pin_config.active_high) - { - nrf_gpiote_task_force(m_nrf_fem_interface_config.pa_pin_config.gpiote_ch_id, - NRF_GPIOTE_INITIAL_VALUE_LOW); - } - else - { - nrf_gpiote_task_force(m_nrf_fem_interface_config.pa_pin_config.gpiote_ch_id, - NRF_GPIOTE_INITIAL_VALUE_HIGH); - } - } - - if (m_nrf_fem_interface_config.lna_pin_config.enable && (type & NRF_802154_FAL_LNA)) - { - if (m_nrf_fem_interface_config.lna_pin_config.active_high) - { - nrf_gpiote_task_force(m_nrf_fem_interface_config.lna_pin_config.gpiote_ch_id, - NRF_GPIOTE_INITIAL_VALUE_LOW); - } - else - { - nrf_gpiote_task_force(m_nrf_fem_interface_config.lna_pin_config.gpiote_ch_id, - NRF_GPIOTE_INITIAL_VALUE_HIGH); - } - } -} - -int32_t nrf_fem_interface_configuration_set(nrf_fem_interface_config_t const * const p_config) -{ - m_nrf_fem_interface_config = *p_config; - - if (m_nrf_fem_interface_config.pa_pin_config.enable || - m_nrf_fem_interface_config.lna_pin_config.enable) - { - gpiote_configure(); - } - - return NRF_SUCCESS; -} - -int32_t nrf_fem_interface_configuration_get(nrf_fem_interface_config_t * p_config) -{ - *p_config = m_nrf_fem_interface_config; - - return NRF_SUCCESS; -} - -void nrf_802154_fal_cleanup(void) -{ - nrf_ppi_channel_disable((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_set); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_set, 0, - 0); - nrf_ppi_fork_endpoint_setup((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_set, 0); - nrf_ppi_channel_disable((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_clr); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_clr, 0, - 0); - nrf_ppi_fork_endpoint_setup((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_clr, 0); - if (m_ppi_channel_ext != PPI_INVALID_CHANNEL) - { - nrf_ppi_channel_disable((nrf_ppi_channel_t)m_ppi_channel_ext); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)m_ppi_channel_ext, 0, 0); - nrf_ppi_fork_endpoint_setup((nrf_ppi_channel_t)m_ppi_channel_ext, 0); - m_ppi_channel_ext = PPI_INVALID_CHANNEL; - } -} - -bool nrf_fem_prepare_powerdown(NRF_TIMER_Type * p_instance, - uint32_t compare_channel, - nrf_ppi_channel_t ppi_id) -{ - uint32_t pdn_task_addr; - - if (!m_nrf_fem_interface_config.pdn_pin_config.enable) - { - return false; - } - - if (m_nrf_fem_interface_config.pdn_pin_config.active_high) - { - pdn_task_addr = - (uint32_t)(&NRF_GPIOTE->TASKS_CLR[m_nrf_fem_interface_config.pdn_pin_config.gpiote_ch_id - ]); - } - else - { - pdn_task_addr = - (uint32_t)(&NRF_GPIOTE->TASKS_SET[m_nrf_fem_interface_config.pdn_pin_config.gpiote_ch_id - ]); - } - - nrf_timer_cc_write(p_instance, - (nrf_timer_cc_channel_t)compare_channel, - m_nrf_fem_interface_config.fem_config.trx_hold_us + 1); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)m_nrf_fem_interface_config.ppi_ch_id_pdn, - (uint32_t)(&(p_instance->EVENTS_COMPARE[compare_channel])), - pdn_task_addr); - - uint32_t event_addr = (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_DISABLED); - uint32_t task_addr = (uint32_t)nrf_timer_task_address_get(p_instance, NRF_TIMER_TASK_START); - - nrf_timer_shorts_enable(p_instance, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - nrf_ppi_channel_endpoint_setup(ppi_id, event_addr, task_addr); - nrf_ppi_fork_endpoint_setup(ppi_id, 0); - nrf_ppi_channel_enable(ppi_id); - - nrf_timer_event_clear(p_instance, NRF_TIMER_EVENT_COMPARE0); - - return true; -} - -#endif // ENABLE_FEM diff --git a/src/mac_features/ack_generator/nrf_802154_ack_data.c b/src/mac_features/ack_generator/nrf_802154_ack_data.c index 2de5a21..50b5d7f 100644 --- a/src/mac_features/ack_generator/nrf_802154_ack_data.c +++ b/src/mac_features/ack_generator/nrf_802154_ack_data.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -199,11 +200,11 @@ static int8_t addr_compare(const uint8_t * p_first_addr, * @retval true Address @p p_addr is in the list. * @retval false Address @p p_addr is not in the list. */ -static bool addr_binary_search(const uint8_t * p_addr, - const uint8_t * p_addr_array, - uint32_t * p_location, - uint8_t data_type, - bool extended) +static bool addr_binary_search(const uint8_t * p_addr, + const uint8_t * p_addr_array, + uint32_t * p_location, + nrf_802154_ack_data_t data_type, + bool extended) { uint32_t addr_array_len = 0; uint8_t entry_size = 0; @@ -288,10 +289,10 @@ static bool addr_binary_search(const uint8_t * p_addr, * @retval true Address @p p_addr is in the list. * @retval false Address @p p_addr is not in the list. */ -static bool addr_index_find(const uint8_t * p_addr, - uint32_t * p_location, - uint8_t data_type, - bool extended) +static bool addr_index_find(const uint8_t * p_addr, + uint32_t * p_location, + nrf_802154_ack_data_t data_type, + bool extended) { uint8_t * p_addr_array; bool valid_data_type = true; @@ -431,7 +432,10 @@ static bool addr_match_standard_compliant(const uint8_t * p_frame) * @retval true Address @p p_addr has been added to the list successfully. * @retval false Address @p p_addr could not be added to the list. */ -static bool addr_add(const uint8_t * p_addr, uint32_t location, uint8_t data_type, bool extended) +static bool addr_add(const uint8_t * p_addr, + uint32_t location, + nrf_802154_ack_data_t data_type, + bool extended) { uint32_t * p_addr_array_len; uint32_t max_addr_array_len; @@ -508,7 +512,7 @@ static bool addr_add(const uint8_t * p_addr, uint32_t location, uint8_t data_typ * @retval true Address @p p_addr has been removed from the list successfully. * @retval false Address @p p_addr could not removed from the list. */ -static bool addr_remove(uint32_t location, uint8_t data_type, bool extended) +static bool addr_remove(uint32_t location, nrf_802154_ack_data_t data_type, bool extended) { uint32_t * p_addr_array_len; uint8_t * p_addr_array; @@ -599,11 +603,11 @@ void nrf_802154_ack_data_enable(bool enabled) m_pending_bit.enabled = enabled; } -bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr, - bool extended, - uint8_t data_type, - const void * p_data, - uint8_t data_len) +bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr, + bool extended, + nrf_802154_ack_data_t data_type, + const void * p_data, + uint8_t data_len) { uint32_t location = 0; @@ -623,7 +627,9 @@ bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr, } } -bool nrf_802154_ack_data_for_addr_clear(const uint8_t * p_addr, bool extended, uint8_t data_type) +bool nrf_802154_ack_data_for_addr_clear(const uint8_t * p_addr, + bool extended, + nrf_802154_ack_data_t data_type) { uint32_t location = 0; @@ -637,7 +643,7 @@ bool nrf_802154_ack_data_for_addr_clear(const uint8_t * p_addr, bool extended, u } } -void nrf_802154_ack_data_reset(bool extended, uint8_t data_type) +void nrf_802154_ack_data_reset(bool extended, nrf_802154_ack_data_t data_type) { switch (data_type) { @@ -703,6 +709,7 @@ bool nrf_802154_ack_data_pending_bit_should_be_set(const uint8_t * p_frame) break; default: + ret = false; assert(false); } diff --git a/src/mac_features/ack_generator/nrf_802154_ack_data.h b/src/mac_features/ack_generator/nrf_802154_ack_data.h index 355959b..30a95e2 100644 --- a/src/mac_features/ack_generator/nrf_802154_ack_data.h +++ b/src/mac_features/ack_generator/nrf_802154_ack_data.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -70,11 +71,11 @@ void nrf_802154_ack_data_enable(bool enabled); * @retval true Address successfully added to the list. * @retval false Address not added to the list (list is full). */ -bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr, - bool extended, - uint8_t data_type, - const void * p_data, - uint8_t data_len); +bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr, + bool extended, + nrf_802154_ack_data_t data_type, + const void * p_data, + uint8_t data_len); /** * @brief Removes an address from the ACK data list. @@ -90,7 +91,9 @@ bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr, * @retval true Address successfully removed from the list. * @retval false Address not removed from the list (address is missing from the list). */ -bool nrf_802154_ack_data_for_addr_clear(const uint8_t * p_addr, bool extended, uint8_t data_type); +bool nrf_802154_ack_data_for_addr_clear(const uint8_t * p_addr, + bool extended, + nrf_802154_ack_data_t data_type); /** * @brief Removes all addresses of a given length from the ACK data list. @@ -99,7 +102,7 @@ bool nrf_802154_ack_data_for_addr_clear(const uint8_t * p_addr, bool extended, u * to be removed from the list. * @param[in] data_type Type of data that is to be cleared for all addresses of a given length. */ -void nrf_802154_ack_data_reset(bool extended, uint8_t data_type); +void nrf_802154_ack_data_reset(bool extended, nrf_802154_ack_data_t data_type); /** * @brief Select the source matching algorithm. diff --git a/src/mac_features/ack_generator/nrf_802154_ack_generator.c b/src/mac_features/ack_generator/nrf_802154_ack_generator.c index a973064..1f2eb3a 100644 --- a/src/mac_features/ack_generator/nrf_802154_ack_generator.c +++ b/src/mac_features/ack_generator/nrf_802154_ack_generator.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/mac_features/ack_generator/nrf_802154_ack_generator.h b/src/mac_features/ack_generator/nrf_802154_ack_generator.h index 561ec80..de80656 100644 --- a/src/mac_features/ack_generator/nrf_802154_ack_generator.h +++ b/src/mac_features/ack_generator/nrf_802154_ack_generator.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c b/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c index 9985758..d289585 100644 --- a/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c +++ b/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -100,7 +101,7 @@ static void fcf_sequence_number_suppression_set(const uint8_t * p_frame) } } -static void fcf_ie_present_set(const uint8_t * p_frame, const uint8_t * p_ie_data) +static void fcf_ie_present_set(const uint8_t * p_ie_data) { if (p_ie_data != NULL) { @@ -124,7 +125,7 @@ static void fcf_dst_addressing_mode_set(const uint8_t * p_frame) } } -static void fcf_src_addressing_mode_set(const uint8_t * p_frame) +static void fcf_src_addressing_mode_set(void) { m_ack_data[SRC_ADDR_TYPE_OFFSET] |= SRC_ADDR_TYPE_NONE; } @@ -145,10 +146,10 @@ static void frame_control_set(const uint8_t * p_frame, fcf_frame_pending_set(p_frame); fcf_panid_compression_set(p_frame); fcf_sequence_number_suppression_set(p_frame); - fcf_ie_present_set(p_frame, p_ie_data); + fcf_ie_present_set(p_ie_data); fcf_dst_addressing_mode_set(p_frame); fcf_frame_version_set(); - fcf_src_addressing_mode_set(p_frame); + fcf_src_addressing_mode_set(); parse_results = nrf_802154_frame_parser_mhr_parse(m_ack_data, p_ack_offsets); assert(parse_results); @@ -195,7 +196,7 @@ static void destination_set(const nrf_802154_frame_parser_mhr_data_t * p_frame, } } -static void source_set(const uint8_t * p_frame) +static void source_set(void) { // Intentionally empty: source address type is None. } @@ -367,7 +368,7 @@ const uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame) destination_set(&frame_offsets, &ack_offsets); // Set source address and PAN ID. - source_set(p_frame); + source_set(); // Set auxiliary security header. security_header_set(&frame_offsets, &ack_offsets, &p_sec_end); diff --git a/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.h b/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.h index 15005db..994e686 100644 --- a/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.h +++ b/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/mac_features/ack_generator/nrf_802154_imm_ack_generator.c b/src/mac_features/ack_generator/nrf_802154_imm_ack_generator.c index 748e622..3c7e9bc 100644 --- a/src/mac_features/ack_generator/nrf_802154_imm_ack_generator.c +++ b/src/mac_features/ack_generator/nrf_802154_imm_ack_generator.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -42,7 +43,7 @@ #include "nrf_802154_ack_data.h" #include "nrf_802154_const.h" -#define IMM_ACK_INITIALIZER {0x05, ACK_HEADER_WITH_PENDING, 0x00, 0x00, 0x00, 0x00} +#define IMM_ACK_INITIALIZER {IMM_ACK_LENGTH, ACK_HEADER_WITH_PENDING, 0x00, 0x00, 0x00, 0x00} static uint8_t m_ack_data[IMM_ACK_LENGTH + PHR_SIZE]; diff --git a/src/mac_features/ack_generator/nrf_802154_imm_ack_generator.h b/src/mac_features/ack_generator/nrf_802154_imm_ack_generator.h index 8504a51..3ce8dc2 100644 --- a/src/mac_features/ack_generator/nrf_802154_imm_ack_generator.h +++ b/src/mac_features/ack_generator/nrf_802154_imm_ack_generator.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/mac_features/nrf_802154_ack_timeout.c b/src/mac_features/nrf_802154_ack_timeout.c index 90ac9a5..c388969 100644 --- a/src/mac_features/nrf_802154_ack_timeout.c +++ b/src/mac_features/nrf_802154_ack_timeout.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -34,6 +35,8 @@ * */ +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_ACK_TIMEOUT + #include "nrf_802154_ack_timeout.h" #include @@ -43,7 +46,7 @@ #include "../nrf_802154_debug.h" #include "nrf_802154_notification.h" #include "nrf_802154_request.h" -#include "timer_scheduler/nrf_802154_timer_sched.h" +#include "timer/nrf_802154_timer_sched.h" #define RETRY_DELAY 500 ///< Procedure is delayed by this time if cannot be performed at the moment. #define MAX_RETRY_DELAY 1000000 ///< Maximal allowed delay of procedure retry. @@ -65,7 +68,7 @@ static void notify_tx_error(bool result) static void timeout_timer_fired(void * p_context) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_ACK_TIMEOUT_FIRED); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); (void)p_context; @@ -84,7 +87,7 @@ static void timeout_timer_fired(void * p_context) } } - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_ACK_TIMEOUT_FIRED); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } static void timeout_timer_retry(void) diff --git a/src/mac_features/nrf_802154_ack_timeout.h b/src/mac_features/nrf_802154_ack_timeout.h index 51a627d..e9fc0b8 100644 --- a/src/mac_features/nrf_802154_ack_timeout.h +++ b/src/mac_features/nrf_802154_ack_timeout.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_ACK_TIMEOUT_H__ diff --git a/src/mac_features/nrf_802154_csma_ca.c b/src/mac_features/nrf_802154_csma_ca.c index d8a5584..34d2b63 100644 --- a/src/mac_features/nrf_802154_csma_ca.c +++ b/src/mac_features/nrf_802154_csma_ca.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -34,6 +35,8 @@ * */ +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_CSMACA + #include "nrf_802154_csma_ca.h" #include @@ -43,20 +46,24 @@ #include "nrf_802154_config.h" #include "nrf_802154_const.h" -#include "../nrf_802154_debug.h" +#include "nrf_802154_debug.h" #include "nrf_802154_notification.h" +#include "nrf_802154_pib.h" +#include "nrf_802154_procedures_duration.h" #include "nrf_802154_request.h" +#include "nrf_802154_stats.h" +#include "mac_features/nrf_802154_frame_parser.h" #include "platform/random/nrf_802154_random.h" -#include "timer_scheduler/nrf_802154_timer_sched.h" +#include "rsch/nrf_802154_rsch.h" +#include "timer/nrf_802154_timer_sched.h" #if NRF_802154_CSMA_CA_ENABLED -static uint8_t m_nb; ///< The number of times the CSMA-CA algorithm was required to back off while attempting the current transmission. -static uint8_t m_be; ///< Backoff exponent, which is related to how many backoff periods a device shall wait before attempting to assess a channel. +static uint8_t m_nb; ///< The number of times the CSMA-CA algorithm was required to back off while attempting the current transmission. +static uint8_t m_be; ///< Backoff exponent, which is related to how many backoff periods a device shall wait before attempting to assess a channel. -static const uint8_t * mp_data; ///< Pointer to a buffer containing PHR and PSDU of the frame being transmitted. -static nrf_802154_timer_t m_timer; ///< Timer used to back off during CSMA-CA procedure. -static bool m_is_running; ///< Indicates if CSMA-CA procedure is running. +static const uint8_t * mp_data; ///< Pointer to a buffer containing PHR and PSDU of the frame being transmitted. +static bool m_is_running; ///< Indicates if CSMA-CA procedure is running. /** * @brief Perform appropriate actions for busy channel conditions. @@ -86,20 +93,50 @@ static bool procedure_is_running(void) */ static void procedure_stop(void) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_rsch_delayed_timeslot_cancel(RSCH_DLY_CSMACA); m_is_running = false; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void priority_leverage(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + bool first_transmit_attempt = (0 == m_nb); + bool coex_requires_boosted_prio = (nrf_802154_pib_coex_tx_request_mode_get() == + NRF_802154_COEX_TX_REQUEST_MODE_CCA_START); + + // Leverage priority only after the first backoff in the specified Coex TX request mode + if (first_transmit_attempt && coex_requires_boosted_prio) + { + // It should always be possible to update this timeslot's priority here + if (!nrf_802154_rsch_delayed_timeslot_priority_update(RSCH_DLY_CSMACA, RSCH_PRIO_TX)) + { + assert(false); + } + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } /** - * Notify MAC layer that channel is busy if tx request failed and there are no retries left. + * @brief Notify MAC layer that channel is busy if tx request failed and there are no retries left. * * @param[in] result Result of TX request. */ static void notify_busy_channel(bool result) { - if (!result && (m_nb >= (NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS - 1))) + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + if (!result && (m_nb >= (nrf_802154_pib_csmaca_max_backoffs_get() - 1))) { nrf_802154_notify_transmit_failed(mp_data, NRF_802154_TX_ERROR_BUSY_CHANNEL); } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } /** @@ -111,14 +148,16 @@ static void notify_busy_channel(bool result) * * @param[in] p_context Unused variable passed from the Timer Scheduler module. */ -static void frame_transmit(void * p_context) +static void frame_transmit(rsch_dly_ts_id_t dly_ts_id) { - (void)p_context; + (void)dly_ts_id; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CSMA_FRAME_TRANSMIT); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); if (procedure_is_running()) { + priority_leverage(); + if (!nrf_802154_request_transmit(NRF_802154_TERM_NONE, REQ_ORIG_CSMA_CA, mp_data, @@ -130,7 +169,7 @@ static void frame_transmit(void * p_context) } } - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CSMA_FRAME_TRANSMIT); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } /** @@ -138,14 +177,56 @@ static void frame_transmit(void * p_context) */ static void random_backoff_start(void) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + uint8_t backoff_periods = nrf_802154_random_get() % (1 << m_be); - m_timer.callback = frame_transmit; - m_timer.p_context = NULL; - m_timer.t0 = nrf_802154_timer_sched_time_get(); - m_timer.dt = backoff_periods * UNIT_BACKOFF_PERIOD; + // If maximum number of CSMA-CA backoffs is equal to 0, this function is called only once + // and no more backoffs will follow. Forcing the first and only backoff to 0 has the same + // effect as no backoff at all. + if (0 == nrf_802154_pib_csmaca_max_backoffs_get()) + { + backoff_periods = 0; + } + + rsch_dly_ts_param_t backoff_ts_param = + { + .t0 = nrf_802154_timer_sched_time_get(), + .dt = backoff_periods * UNIT_BACKOFF_PERIOD, + .id = RSCH_DLY_CSMACA, + .type = RSCH_DLY_TS_TYPE_RELAXED, + .started_callback = frame_transmit, + }; + + switch (nrf_802154_pib_coex_tx_request_mode_get()) + { + case NRF_802154_COEX_TX_REQUEST_MODE_FRAME_READY: + // To request Coex precondition immediately, priority must be leveraged + backoff_ts_param.prio = RSCH_PRIO_TX; + break; + + case NRF_802154_COEX_TX_REQUEST_MODE_CCA_START: + // Coex should be requested for all backoff periods but the first one + backoff_ts_param.prio = (m_nb == 0) ? RSCH_PRIO_IDLE_LISTENING : RSCH_PRIO_TX; + break; + + case NRF_802154_COEX_TX_REQUEST_MODE_CCA_DONE: + // Coex should not be requested during backoff periods + backoff_ts_param.prio = RSCH_PRIO_IDLE_LISTENING; + break; + + default: + assert(false); + break; + } + + // Delayed timeslot with these parameters should always be scheduled + if (!nrf_802154_rsch_delayed_timeslot_request(&backoff_ts_param)) + { + assert(false); + } - nrf_802154_timer_sched_add(&m_timer, false); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } static bool channel_busy(void) @@ -154,16 +235,16 @@ static bool channel_busy(void) if (procedure_is_running()) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CSMA_CHANNEL_BUSY); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); m_nb++; - if (m_be < NRF_802154_CSMA_CA_MAX_BE) + if (m_be < nrf_802154_pib_csmaca_max_be_get()) { m_be++; } - if (m_nb < NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS) + if (m_nb < nrf_802154_pib_csmaca_max_backoffs_get()) { random_backoff_start(); result = false; @@ -173,7 +254,7 @@ static bool channel_busy(void) procedure_stop(); } - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CSMA_CHANNEL_BUSY); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } return result; @@ -181,43 +262,50 @@ static bool channel_busy(void) void nrf_802154_csma_ca_start(const uint8_t * p_data) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + +#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) + uint32_t ts = nrf_802154_timer_sched_time_get(); + + nrf_802154_stat_timestamp_write(last_csmaca_start_timestamp, ts); +#endif + assert(!procedure_is_running()); mp_data = p_data; m_nb = 0; - m_be = NRF_802154_CSMA_CA_MIN_BE; + m_be = nrf_802154_pib_csmaca_min_be_get(); m_is_running = true; random_backoff_start(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } bool nrf_802154_csma_ca_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig) { - bool result = false; - // Stop CSMA-CA only if request by the core or the higher layer. if ((req_orig != REQ_ORIG_CORE) && (req_orig != REQ_ORIG_HIGHER_LAYER)) { return true; } - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CSMA_ABORT); + bool result = true; + + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); if (term_lvl >= NRF_802154_TERM_802154) { // Stop CSMA-CA if termination level is high enough. - nrf_802154_timer_sched_remove(&m_timer, NULL); procedure_stop(); - - result = true; } - else if (!procedure_is_running()) + else { // Return success in case procedure is already stopped. - result = true; + result = !procedure_is_running(); } - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CSMA_ABORT); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -230,11 +318,11 @@ bool nrf_802154_csma_ca_tx_failed_hook(const uint8_t * p_frame, nrf_802154_tx_er if (p_frame == mp_data) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CSMA_TX_FAILED); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = channel_busy(); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CSMA_TX_FAILED); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } return result; @@ -244,12 +332,11 @@ bool nrf_802154_csma_ca_tx_started_hook(const uint8_t * p_frame) { if (p_frame == mp_data) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CSMA_TX_STARTED); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - assert(!nrf_802154_timer_sched_is_running(&m_timer)); procedure_stop(); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CSMA_TX_STARTED); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } return true; diff --git a/src/mac_features/nrf_802154_csma_ca.h b/src/mac_features/nrf_802154_csma_ca.h index 58df07c..42923ef 100644 --- a/src/mac_features/nrf_802154_csma_ca.h +++ b/src/mac_features/nrf_802154_csma_ca.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_CSMA_CA_H__ diff --git a/src/mac_features/nrf_802154_delayed_trx.c b/src/mac_features/nrf_802154_delayed_trx.c index 566d09a..a7ac5b2 100644 --- a/src/mac_features/nrf_802154_delayed_trx.c +++ b/src/mac_features/nrf_802154_delayed_trx.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -34,6 +35,8 @@ * */ +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_DELAYED_TRX + #include "nrf_802154_delayed_trx.h" #include @@ -49,13 +52,15 @@ #include "nrf_802154_procedures_duration.h" #include "nrf_802154_request.h" #include "rsch/nrf_802154_rsch.h" -#include "timer_scheduler/nrf_802154_timer_sched.h" +#include "timer/nrf_802154_timer_sched.h" + +#if NRF_802154_DELAYED_TRX_ENABLED /* The following time is the sum of 70us RTC_IRQHandler processing time, 40us of time that elapses * from the moment a board starts transmission to the moment other boards (e.g. sniffer) are able - * to detect that frame and in case of TX - 50us that accounts for a delay of yet unknown origin. + * to detect that frame and in case of TX - 93us that accounts for a delay of yet unknown origin. */ -#define TX_SETUP_TIME 160u ///< Time needed to prepare TX procedure [us]. It does not include TX ramp-up time. +#define TX_SETUP_TIME 203u ///< Time needed to prepare TX procedure [us]. It does not include TX ramp-up time. #define RX_SETUP_TIME 110u ///< Time needed to prepare RX procedure [us]. It does not include RX ramp-up time. /** @@ -191,31 +196,22 @@ static void dly_op_state_set(rsch_dly_ts_id_t dly_ts_id, /** * Start delayed operation. * - * @param[in] t0 Base time of the timestamp of the timeslot start [us]. - * @param[in] dt Time delta between @p t0 and the timestamp of the timeslot start [us]. - * @param[in] length Requested radio timeslot length [us]. - * @param[in] dly_ts Delayed timeslot ID. + * @param[in] p_dly_ts_param Parameters of the requested delayed timeslot. */ -static bool dly_op_request(uint32_t t0, - uint32_t dt, - uint32_t length, - rsch_dly_ts_id_t dly_ts_id) +static bool dly_op_request(const rsch_dly_ts_param_t * p_dly_ts_param) { - bool result; - // Set PENDING state before timeslot request, in case timeslot starts - // immediatly and interrupts current function execution. - dly_op_state_set(dly_ts_id, DELAYED_TRX_OP_STATE_STOPPED, DELAYED_TRX_OP_STATE_PENDING); + // immediately and interrupts current function execution. + dly_op_state_set(p_dly_ts_param->id, DELAYED_TRX_OP_STATE_STOPPED, + DELAYED_TRX_OP_STATE_PENDING); - result = nrf_802154_rsch_delayed_timeslot_request(t0, - dt, - length, - RSCH_PRIO_MAX, - dly_ts_id); + bool result = nrf_802154_rsch_delayed_timeslot_request(p_dly_ts_param); if (!result) { - dly_op_state_set(dly_ts_id, DELAYED_TRX_OP_STATE_PENDING, DELAYED_TRX_OP_STATE_STOPPED); + dly_op_state_set(p_dly_ts_param->id, + DELAYED_TRX_OP_STATE_PENDING, + DELAYED_TRX_OP_STATE_STOPPED); } return result; @@ -230,7 +226,7 @@ static void notify_rx_timeout(void * p_context) { (void)p_context; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_DTRX_RX_TIMEOUT); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); assert(dly_op_state_get(RSCH_DLY_RX) != DELAYED_TRX_OP_STATE_PENDING); @@ -267,7 +263,7 @@ static void notify_rx_timeout(void * p_context) } } - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_DTRX_RX_TIMEOUT); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } /** @@ -275,7 +271,7 @@ static void notify_rx_timeout(void * p_context) * * @param[in] result Result of TX request. */ -static void tx_timeslot_started_callback(bool result) +static void dly_tx_result_notify(bool result) { (void)result; @@ -295,7 +291,7 @@ static void tx_timeslot_started_callback(bool result) * * @param[in] result Result of RX request. */ -static void rx_timeslot_started_callback(bool result) +static void dly_rx_result_notify(bool result) { if (result) { @@ -321,51 +317,91 @@ static void rx_timeslot_started_callback(bool result) } /** - * Handle TX timeslot start. + * Notify that the previously requested delayed TX timeslot has started just now. + * + * @param[in] dly_ts_id ID of the started timeslot. */ -static void tx_timeslot_started_callout(void) +static void tx_timeslot_started_callback(rsch_dly_ts_id_t dly_ts_id) { - bool result; + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); - nrf_802154_pib_channel_set(m_tx_channel); - result = nrf_802154_request_channel_update(); + assert(dly_ts_id == RSCH_DLY_TX); - if (result) - { - (void)nrf_802154_request_transmit(NRF_802154_TERM_802154, - REQ_ORIG_DELAYED_TRX, - mp_tx_data, - m_tx_cca, - true, - tx_timeslot_started_callback); - } - else + switch (dly_op_state_get(dly_ts_id)) { - tx_timeslot_started_callback(result); + case DELAYED_TRX_OP_STATE_PENDING: + { + nrf_802154_pib_channel_set(m_tx_channel); + + if (nrf_802154_request_channel_update()) + { + (void)nrf_802154_request_transmit(NRF_802154_TERM_802154, + REQ_ORIG_DELAYED_TRX, + mp_tx_data, + m_tx_cca, + true, + dly_tx_result_notify); + } + else + { + dly_tx_result_notify(false); + } + + break; + } + + case DELAYED_TRX_OP_STATE_STOPPED: + break; + + default: + assert(false); + break; } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } /** - * Handle RX timeslot start. + * Notify that the previously requested delayed RX timeslot has started just now. + * + * @param[in] dly_ts_id ID of the started timeslot. */ -static void rx_timeslot_started_callout(void) +static void rx_timeslot_started_callback(rsch_dly_ts_id_t dly_ts_id) { - bool result; + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); - nrf_802154_pib_channel_set(m_rx_channel); - result = nrf_802154_request_channel_update(); + assert(dly_ts_id == RSCH_DLY_RX); - if (result) - { - (void)nrf_802154_request_receive(NRF_802154_TERM_802154, - REQ_ORIG_DELAYED_TRX, - rx_timeslot_started_callback, - true); - } - else + switch (dly_op_state_get(dly_ts_id)) { - rx_timeslot_started_callback(result); + case DELAYED_TRX_OP_STATE_PENDING: + { + nrf_802154_pib_channel_set(m_rx_channel); + + if (nrf_802154_request_channel_update()) + { + (void)nrf_802154_request_receive(NRF_802154_TERM_802154, + REQ_ORIG_DELAYED_TRX, + dly_rx_result_notify, + true); + } + else + { + dly_rx_result_notify(false); + } + + break; + } + + case DELAYED_TRX_OP_STATE_STOPPED: + break; + + default: + assert(false); + break; } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } bool nrf_802154_delayed_trx_transmit(const uint8_t * p_data, @@ -374,11 +410,7 @@ bool nrf_802154_delayed_trx_transmit(const uint8_t * p_data, uint32_t dt, uint8_t channel) { - bool result; - uint16_t timeslot_length; - bool ack; - - result = dly_op_state_get(RSCH_DLY_TX) == DELAYED_TRX_OP_STATE_STOPPED; + bool result = dly_op_state_get(RSCH_DLY_TX) == DELAYED_TRX_OP_STATE_STOPPED; if (result) { @@ -390,14 +422,21 @@ bool nrf_802154_delayed_trx_transmit(const uint8_t * p_data, dt -= nrf_802154_cca_before_tx_duration_get(); } - ack = p_data[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT; - timeslot_length = nrf_802154_tx_duration_get(p_data[0], cca, ack); - mp_tx_data = p_data; m_tx_cca = cca; m_tx_channel = channel; - result = dly_op_request(t0, dt, timeslot_length, RSCH_DLY_TX); + rsch_dly_ts_param_t dly_ts_param = + { + .t0 = t0, + .dt = dt, + .prio = RSCH_PRIO_TX, + .id = RSCH_DLY_TX, + .type = RSCH_DLY_TS_TYPE_PRECISE, + .started_callback = tx_timeslot_started_callback, + }; + + result = dly_op_request(&dly_ts_param); } return result; @@ -408,19 +447,13 @@ bool nrf_802154_delayed_trx_receive(uint32_t t0, uint32_t timeout, uint8_t channel) { - bool result; - uint16_t timeslot_length; - - result = dly_op_state_get(RSCH_DLY_RX) == DELAYED_TRX_OP_STATE_STOPPED; + bool result = dly_op_state_get(RSCH_DLY_RX) == DELAYED_TRX_OP_STATE_STOPPED; if (result) { - dt -= RX_SETUP_TIME; dt -= RX_RAMP_UP_TIME; - timeslot_length = timeout + nrf_802154_rx_duration_get(MAX_PACKET_SIZE, true); - m_timeout_timer.dt = timeout + RX_RAMP_UP_TIME; m_timeout_timer.callback = notify_rx_timeout; m_timeout_timer.p_context = NULL; @@ -430,52 +463,26 @@ bool nrf_802154_delayed_trx_receive(uint32_t t0, // remove timer in case it was left after abort operation nrf_802154_timer_sched_remove(&m_timeout_timer, NULL); - result = dly_op_request(t0, dt, timeslot_length, RSCH_DLY_RX); + rsch_dly_ts_param_t dly_ts_param = + { + .t0 = t0, + .dt = dt, + .prio = RSCH_PRIO_IDLE_LISTENING, + .id = RSCH_DLY_RX, + .type = RSCH_DLY_TS_TYPE_PRECISE, + .started_callback = rx_timeslot_started_callback, + }; + + result = dly_op_request(&dly_ts_param); } return result; } -static inline void timeslot_started_callout(rsch_dly_ts_id_t dly_ts_id) -{ - switch (dly_ts_id) - { - case RSCH_DLY_TX: - tx_timeslot_started_callout(); - break; - - case RSCH_DLY_RX: - rx_timeslot_started_callout(); - break; - - default: - assert(false); - break; - } -} - -void nrf_802154_rsch_delayed_timeslot_started(rsch_dly_ts_id_t dly_ts_id) -{ - switch (dly_op_state_get(dly_ts_id)) - { - case DELAYED_TRX_OP_STATE_PENDING: - timeslot_started_callout(dly_ts_id); - break; - - case DELAYED_TRX_OP_STATE_STOPPED: - /* Intentionally do nothing */ - break; - - default: - assert(false); - } -} - bool nrf_802154_delayed_trx_transmit_cancel(void) { - bool result; + bool result = nrf_802154_rsch_delayed_timeslot_cancel(RSCH_DLY_TX); - result = nrf_802154_rsch_delayed_timeslot_cancel(RSCH_DLY_TX); m_dly_op_state[RSCH_DLY_TX] = DELAYED_TRX_OP_STATE_STOPPED; return result; @@ -483,10 +490,7 @@ bool nrf_802154_delayed_trx_transmit_cancel(void) bool nrf_802154_delayed_trx_receive_cancel(void) { - bool result; - - result = nrf_802154_rsch_delayed_timeslot_cancel(RSCH_DLY_RX); - + bool result = nrf_802154_rsch_delayed_timeslot_cancel(RSCH_DLY_RX); bool was_running; nrf_802154_timer_sched_remove(&m_timeout_timer, &was_running); @@ -537,3 +541,5 @@ void nrf_802154_delayed_trx_rx_started_hook(const uint8_t * p_frame) m_dly_rx_frame.ack_requested = nrf_802154_frame_parser_ar_bit_is_set(p_frame); } } + +#endif // NRF_802154_DELAYED_TRX_ENABLED diff --git a/src/mac_features/nrf_802154_delayed_trx.h b/src/mac_features/nrf_802154_delayed_trx.h index 45d94fe..dce7e15 100644 --- a/src/mac_features/nrf_802154_delayed_trx.h +++ b/src/mac_features/nrf_802154_delayed_trx.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_DELAYED_TRX_H__ @@ -37,6 +38,8 @@ #include "nrf_802154_const.h" #include "nrf_802154_types.h" +#if NRF_802154_DELAYED_TRX_ENABLED + /** * @defgroup nrf_802154_delayed_trx Delayed transmission and reception window features * @{ @@ -144,4 +147,6 @@ void nrf_802154_delayed_trx_rx_started_hook(const uint8_t * p_frame); *@} **/ +#endif // NRF_802154_DELAYED_TRX_ENABLED + #endif // NRF_802154_DELAYED_TRX_H__ diff --git a/src/mac_features/nrf_802154_filter.c b/src/mac_features/nrf_802154_filter.c index 3060766..d0cd7cf 100644 --- a/src/mac_features/nrf_802154_filter.c +++ b/src/mac_features/nrf_802154_filter.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -333,12 +334,11 @@ static bool dst_pan_id_check(const uint8_t * p_panid, uint8_t frame_type) * Verify if destination short address of incoming frame allows processing by this node. * * @param[in] p_dst_addr Pointer of destination address of incoming frame. - * @param[in] frame_type Type of the frame being filtered. * * @retval true Destination address of incoming frame allows further processing of the frame. * @retval false Destination address of incoming frame does not allow further processing. */ -static bool dst_short_addr_check(const uint8_t * p_dst_addr, uint8_t frame_type) +static bool dst_short_addr_check(const uint8_t * p_dst_addr) { bool result; @@ -359,12 +359,11 @@ static bool dst_short_addr_check(const uint8_t * p_dst_addr, uint8_t frame_type) * Verify if destination extended address of incoming frame allows processing by this node. * * @param[in] p_dst_addr Pointer of destination address of incoming frame. - * @param[in] frame_type Type of the frame being filtered. * * @retval true Destination address of incoming frame allows further processing of the frame. * @retval false Destination address of incoming frame does not allow further processing. */ -static bool dst_extended_addr_check(const uint8_t * p_dst_addr, uint8_t frame_type) +static bool dst_extended_addr_check(const uint8_t * p_dst_addr) { bool result; @@ -413,13 +412,11 @@ static nrf_802154_rx_error_t dst_addr_check(const uint8_t * p_data, uint8_t fram switch (mhr_data.dst_addr_size) { case SHORT_ADDRESS_SIZE: - return dst_short_addr_check(mhr_data.p_dst_addr, - frame_type) ? NRF_802154_RX_ERROR_NONE : + return dst_short_addr_check(mhr_data.p_dst_addr) ? NRF_802154_RX_ERROR_NONE : NRF_802154_RX_ERROR_INVALID_DEST_ADDR; case EXTENDED_ADDRESS_SIZE: - return dst_extended_addr_check(mhr_data.p_dst_addr, - frame_type) ? NRF_802154_RX_ERROR_NONE : + return dst_extended_addr_check(mhr_data.p_dst_addr) ? NRF_802154_RX_ERROR_NONE : NRF_802154_RX_ERROR_INVALID_DEST_ADDR; case 0: diff --git a/src/mac_features/nrf_802154_filter.h b/src/mac_features/nrf_802154_filter.h index 0796a90..ff57ed1 100644 --- a/src/mac_features/nrf_802154_filter.h +++ b/src/mac_features/nrf_802154_filter.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/mac_features/nrf_802154_frame_parser.c b/src/mac_features/nrf_802154_frame_parser.c index 0ad70e2..7bb0108 100644 --- a/src/mac_features/nrf_802154_frame_parser.c +++ b/src/mac_features/nrf_802154_frame_parser.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/mac_features/nrf_802154_frame_parser.h b/src/mac_features/nrf_802154_frame_parser.h index 0b216d3..649fc35 100644 --- a/src/mac_features/nrf_802154_frame_parser.h +++ b/src/mac_features/nrf_802154_frame_parser.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -42,7 +43,7 @@ #define NRF_802154_FRAME_PARSER_INVALID_OFFSET 0xff /** - * @biref Structure that contains pointers to parts of MHR and details of MHR structure. + * @brief Structure that contains pointers to parts of MHR and details of MHR structure. */ typedef struct { diff --git a/src/mac_features/nrf_802154_ifs.c b/src/mac_features/nrf_802154_ifs.c new file mode 100644 index 0000000..effd8e6 --- /dev/null +++ b/src/mac_features/nrf_802154_ifs.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements Long/Short Interframe Spacing handling procedure for the 802.15.4 driver. + * + */ + +#include "nrf_802154_ifs.h" + +#include +#include +#include + +#include "nrf_802154_pib.h" +#include "nrf_802154_request.h" +#include "mac_features/nrf_802154_frame_parser.h" +#include "timer/nrf_802154_timer_sched.h" + +#if NRF_802154_IFS_ENABLED +typedef struct +{ + uint8_t * p_data; + bool cca; +} ifs_operation_t; + +static union +{ + uint8_t sh[SHORT_ADDRESS_SIZE]; ///< Short address of the last frame transmitted. + uint8_t ext[EXTENDED_ADDRESS_SIZE]; ///< Extended address of the last frame transmitted. +} m_last_address; + +static bool m_is_last_address_extended; ///< Whether the last transmitted frame had the extended address populated. +static uint32_t m_last_frame_timestamp; ///< Timestamp of the last transmitted frame (end of frame). +static uint8_t m_last_frame_length; ///< Length in bytes of the last transmitted frame. +static ifs_operation_t m_context; ///< Context passed to the timer. +static nrf_802154_timer_t m_timer; ///< Interframe space timer. + +static void ifs_tx_result_notify(bool result) +{ + if (!result) + { + nrf_802154_notify_transmit_failed(m_context.p_data, NRF_802154_TX_ERROR_TIMESLOT_DENIED); + } +} + +static void callback_fired(void * p_context) +{ + ifs_operation_t * p_ctx = (ifs_operation_t *)p_context; + + nrf_802154_request_transmit(NRF_802154_TERM_NONE, + REQ_ORIG_IFS, + p_ctx->p_data, + p_ctx->cca, + true, + ifs_tx_result_notify); +} + +/**@brief Checks if the IFS is needed by comparing the addresses of the actual and the last frames. */ +static bool is_ifs_needed_by_address(const uint8_t * p_frame) +{ + bool is_extended; + + const uint8_t * addr = nrf_802154_frame_parser_dst_addr_get(p_frame, &is_extended); + + if (!addr) + { + return true; + } + + if (is_extended == m_is_last_address_extended) + { + uint8_t * last_addr = is_extended ? m_last_address.ext : m_last_address.sh; + size_t addr_len = is_extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE; + + if (0 == memcmp(addr, last_addr, addr_len)) + { + return true; + } + } + + return false; +} + +/**@brief Checks if the IFS is needed by measuring time between the actual and the last frames. + * Returns the needed ifs, 0 if none. + */ +static uint16_t ifs_needed_by_time(uint32_t current_timestamp) +{ + if (!nrf_802154_timer_sched_time_is_in_future(m_last_frame_timestamp, 0, current_timestamp)) + { + /* Explicitly allow case where the timstamps are equal, i.e. we are running very fast. */ + if (current_timestamp != m_last_frame_timestamp) + { + return 0; + } + } + uint16_t ifs_period; + uint32_t dt = current_timestamp - m_last_frame_timestamp; + + if (m_last_frame_length > MAX_SIFS_FRAME_SIZE) + { + ifs_period = nrf_802154_pib_ifs_min_lifs_period_get(); + } + else + { + ifs_period = nrf_802154_pib_ifs_min_sifs_period_get(); + } + + if (dt > ifs_period) + { + return 0; + } + + return ifs_period; +} + +bool nrf_802154_ifs_pretransmission(const uint8_t * p_frame, bool cca) +{ + nrf_802154_ifs_mode_t mode = nrf_802154_pib_ifs_mode_get(); + + if (mode == NRF_802154_IFS_MODE_DISABLED) + { + // Functionality is disabled - skip the routine. + return true; + } + + if (!m_last_frame_length) + { + // No frame was transmitted before - skip the routine. + return true; + } + + if ((mode == NRF_802154_IFS_MODE_MATCHING_ADDRESSES) && !is_ifs_needed_by_address(p_frame)) + { + return true; + } + + uint32_t current_timestamp = nrf_802154_timer_sched_time_get(); + uint32_t dt = ifs_needed_by_time(current_timestamp); + + if (dt == 0) + { + return true; + } + + m_context.p_data = (uint8_t *)p_frame; + m_context.cca = cca; + m_timer.t0 = m_last_frame_timestamp; + m_timer.dt = dt; + m_timer.callback = callback_fired; + m_timer.p_context = &m_context; + + nrf_802154_timer_sched_add(&m_timer, true); + + return false; +} + +void nrf_802154_ifs_transmitted_hook(const uint8_t * p_frame) +{ + assert(p_frame[0] != 0U); + + m_last_frame_timestamp = nrf_802154_timer_sched_time_get(); + + const uint8_t * addr = + nrf_802154_frame_parser_dst_addr_get(p_frame, &m_is_last_address_extended); + + if (!addr) + { + // If the transmitted frame has no address, we consider that enough time has passed so no IFS insertion will be needed. + m_last_frame_length = 0; + return; + } + + if (m_is_last_address_extended) + { + memcpy(m_last_address.ext, addr, EXTENDED_ADDRESS_SIZE); + } + else + { + memcpy(m_last_address.sh, addr, SHORT_ADDRESS_SIZE); + } + + m_last_frame_length = p_frame[0]; +} + +bool nrf_802154_ifs_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig) +{ + bool result = true; + bool was_running; + + if (req_orig == REQ_ORIG_IFS) + { + // Ignore if self-request. + } + else + { + if (term_lvl >= NRF_802154_TERM_802154) + { + nrf_802154_timer_sched_remove(&m_timer, &was_running); + if (was_running) + { + ifs_operation_t * p_op = (ifs_operation_t *)m_timer.p_context; + + nrf_802154_notify_transmit_failed(p_op->p_data, NRF_802154_TX_ERROR_ABORTED); + } + } + else + { + result = !nrf_802154_timer_sched_is_running(&m_timer); + } + } + + return result; +} + +#endif // NRF_802154_IFS_ENABLED diff --git a/src/mac_features/nrf_802154_ifs.h b/src/mac_features/nrf_802154_ifs.h new file mode 100644 index 0000000..954db2f --- /dev/null +++ b/src/mac_features/nrf_802154_ifs.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_802154_IFS_H +#define NRF_802154_IFS_H + +#include +#include + +#include "nrf_802154_const.h" +#include "nrf_802154_types.h" + +/** + * @brief Examines the frame before transmission and checks if it needs to be delayed. + * + * @param[in] p_frame Pointer to the buffer that contains the PHR and PSDU of the transmitted frame. + * @param[in] cca Whether to trigger CCA before transmitting the frame. + * + * @retval true Frame will be transmitted right away. + * @retval false Frame is delayed and will be transmistted after a needed IFS. + */ +bool nrf_802154_ifs_pretransmission(const uint8_t * p_frame, bool cca); + +/** + * @brief Captures the timestamp, length and destination address of the transmitted + * frame for the sake of future analysis by the @ref nrf_802154_ifs_pretransmission + * + * @param[in] p_frame Pointer to the buffer that contains the PHR and PSDU of the transmitted frame. + */ +void nrf_802154_ifs_transmitted_hook(const uint8_t * p_frame); + +/** + * @brief Aborts an ongoing IFS-delayed transmission. + * + * @param[in] term_lvl Termination level set by the request to abort the ongoing operation. + * @param[in] req_orig Module that originates this request. + * + * @retval true Transmission procedure have been stopped. + * @retval false Transmission procedure were not running. + * + */ +bool nrf_802154_ifs_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig); + +#endif // NRF_802154_IFS_H diff --git a/src/mac_features/nrf_802154_precise_ack_timeout.c b/src/mac_features/nrf_802154_precise_ack_timeout.c index 629d640..f3a20f4 100644 --- a/src/mac_features/nrf_802154_precise_ack_timeout.c +++ b/src/mac_features/nrf_802154_precise_ack_timeout.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -34,6 +35,8 @@ * */ +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_ACK_TIMEOUT + #include "nrf_802154_ack_timeout.h" #include @@ -44,7 +47,9 @@ #include "nrf_802154_notification.h" #include "nrf_802154_procedures_duration.h" #include "nrf_802154_request.h" -#include "timer_scheduler/nrf_802154_timer_sched.h" +#include "timer/nrf_802154_timer_sched.h" + +#if NRF_802154_ACK_TIMEOUT_ENABLED #define RETRY_DELAY 500 ///< Procedure is delayed by this time if it cannot be performed at the moment [us]. #define MAX_RETRY_DELAY 1000000 ///< Maximum allowed delay of procedure retry [us]. @@ -66,7 +71,7 @@ static void notify_tx_error(bool result) static void timeout_timer_fired(void * p_context) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_ACK_TIMEOUT_FIRED); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); (void)p_context; @@ -85,7 +90,7 @@ static void timeout_timer_fired(void * p_context) } } - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_ACK_TIMEOUT_FIRED); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } static void timeout_timer_retry(void) @@ -181,3 +186,5 @@ bool nrf_802154_ack_timeout_tx_failed_hook(const uint8_t * p_frame, nrf_802154_t return true; } + +#endif // NRF_802154_ACK_TIMEOUT_ENABLED diff --git a/src/nrf_802154.c b/src/nrf_802154.c index 02d9fdb..4d03c9c 100644 --- a/src/nrf_802154.c +++ b/src/nrf_802154.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -34,6 +35,8 @@ * */ +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_APPLICATION + #include "nrf_802154.h" #include @@ -48,29 +51,29 @@ #include "nrf_802154_critical_section.h" #include "nrf_802154_debug.h" #include "nrf_802154_notification.h" +#include "nrf_802154_nrfx_addons.h" #include "nrf_802154_pib.h" -#include "nrf_802154_priority_drop.h" #include "nrf_802154_request.h" #include "nrf_802154_rssi.h" #include "nrf_802154_rx_buffer.h" -#include "nrf_802154_timer_coord.h" -#include "nrf_radio.h" +#include "nrf_802154_stats.h" +#include "hal/nrf_radio.h" #include "platform/clock/nrf_802154_clock.h" #include "platform/lp_timer/nrf_802154_lp_timer.h" #include "platform/random/nrf_802154_random.h" #include "platform/temperature/nrf_802154_temperature.h" #include "rsch/nrf_802154_rsch.h" #include "rsch/nrf_802154_rsch_crit_sect.h" -#include "timer_scheduler/nrf_802154_timer_sched.h" +#include "rsch/nrf_802154_rsch_prio_drop.h" +#include "timer/nrf_802154_timer_coord.h" +#include "timer/nrf_802154_timer_sched.h" #include "mac_features/nrf_802154_ack_timeout.h" #include "mac_features/nrf_802154_csma_ca.h" #include "mac_features/nrf_802154_delayed_trx.h" #include "mac_features/ack_generator/nrf_802154_ack_data.h" -#if ENABLE_FEM -#include "fem/nrf_fem_protocol_api.h" -#endif +#include "nrf_802154_sl_ant_div.h" #define RAW_LENGTH_OFFSET 0 #define RAW_PAYLOAD_OFFSET 1 @@ -101,39 +104,6 @@ static void tx_buffer_fill(const uint8_t * p_data, uint8_t length) #endif // !NRF_802154_USE_RAW_API -/** - * @brief Get timestamp of the last received frame. - * - * @note This function increments the returned value by 1 us if the timestamp is equal to the - * @ref NRF_802154_NO_TIMESTAMP value to indicate that the timestamp is available. - * - * @returns Timestamp [us] of the last received frame or @ref NRF_802154_NO_TIMESTAMP if - * the timestamp is inaccurate. - */ -static uint32_t last_rx_frame_timestamp_get(void) -{ -#if NRF_802154_FRAME_TIMESTAMP_ENABLED - uint32_t timestamp; - bool timestamp_received = nrf_802154_timer_coord_timestamp_get(×tamp); - - if (!timestamp_received) - { - timestamp = NRF_802154_NO_TIMESTAMP; - } - else - { - if (timestamp == NRF_802154_NO_TIMESTAMP) - { - timestamp++; - } - } - - return timestamp; -#else // NRF_802154_FRAME_TIMESTAMP_ENABLED - return NRF_802154_NO_TIMESTAMP; -#endif // NRF_802154_FRAME_TIMESTAMP_ENABLED -} - void nrf_802154_channel_set(uint8_t channel) { bool changed = nrf_802154_pib_channel_get() != channel; @@ -161,6 +131,26 @@ int8_t nrf_802154_tx_power_get(void) return nrf_802154_pib_tx_power_get(); } +bool nrf_802154_coex_rx_request_mode_set(nrf_802154_coex_rx_request_mode_t mode) +{ + return nrf_802154_pib_coex_rx_request_mode_set(mode); +} + +nrf_802154_coex_rx_request_mode_t nrf_802154_coex_rx_request_mode_get(void) +{ + return nrf_802154_pib_coex_rx_request_mode_get(); +} + +bool nrf_802154_coex_tx_request_mode_set(nrf_802154_coex_tx_request_mode_t mode) +{ + return nrf_802154_pib_coex_tx_request_mode_set(mode); +} + +nrf_802154_coex_tx_request_mode_t nrf_802154_coex_tx_request_mode_get(void) +{ + return nrf_802154_pib_coex_tx_request_mode_get(); +} + void nrf_802154_temperature_changed(void) { nrf_802154_request_cca_cfg_update(); @@ -202,6 +192,12 @@ uint32_t nrf_802154_first_symbol_timestamp_get(uint32_t end_timestamp, uint8_t p void nrf_802154_init(void) { + nrf_802154_sl_crit_sect_interface_t crit_sect_int = + { + .enter = nrf_802154_critical_section_enter, + .exit = nrf_802154_critical_section_exit + }; + nrf_802154_ack_data_init(); nrf_802154_core_init(); nrf_802154_clock_init(); @@ -210,10 +206,10 @@ void nrf_802154_init(void) nrf_802154_notification_init(); nrf_802154_lp_timer_init(); nrf_802154_pib_init(); - nrf_802154_priority_drop_init(); + nrf_802154_rsch_prio_drop_init(); nrf_802154_random_init(); nrf_802154_request_init(); - nrf_802154_rsch_crit_sect_init(); + nrf_802154_rsch_crit_sect_init(&crit_sect_int); nrf_802154_rsch_init(); nrf_802154_rx_buffer_init(); nrf_802154_temperature_init(); @@ -233,59 +229,116 @@ void nrf_802154_deinit(void) nrf_802154_core_deinit(); } -#if !NRF_802154_INTERNAL_RADIO_IRQ_HANDLING -void nrf_802154_radio_irq_handler(void) +bool nrf_802154_antenna_diversity_rx_mode_set(nrf_802154_sl_ant_div_mode_t mode) { - nrf_802154_core_irq_handler(); + bool result = false; + +#if defined(RADIO_INTENSET_SYNC_Msk) + result = nrf_802154_sl_ant_div_cfg_mode_set(NRF_802154_SL_ANT_DIV_OP_RX, mode); +#endif + + if (result) + { + nrf_802154_request_antenna_update(); + } + + return result; } -#endif // !NRF_802154_INTERNAL_RADIO_IRQ_HANDLING +nrf_802154_sl_ant_div_mode_t nrf_802154_antenna_diversity_rx_mode_get(void) +{ + return nrf_802154_sl_ant_div_cfg_mode_get(NRF_802154_SL_ANT_DIV_OP_RX); +} -#if ENABLE_FEM -void nrf_802154_fem_control_cfg_set(nrf_802154_fem_control_cfg_t const * const p_cfg) +bool nrf_802154_antenna_diversity_tx_mode_set(nrf_802154_sl_ant_div_mode_t mode) { - nrf_fem_interface_config_t config; + bool result = false; - nrf_fem_interface_configuration_get(&config); +#if defined(RADIO_INTENSET_SYNC_Msk) + result = nrf_802154_sl_ant_div_cfg_mode_set(NRF_802154_SL_ANT_DIV_OP_TX, mode); +#endif - config.lna_pin_config.active_high = p_cfg->lna_cfg.active_high; - config.lna_pin_config.enable = p_cfg->lna_cfg.enable; - config.lna_pin_config.gpio_pin = p_cfg->lna_cfg.gpio_pin; - config.lna_pin_config.gpiote_ch_id = p_cfg->lna_gpiote_ch_id; + if (result) + { + nrf_802154_request_antenna_update(); + } - config.pa_pin_config.active_high = p_cfg->pa_cfg.active_high; - config.pa_pin_config.enable = p_cfg->pa_cfg.enable; - config.pa_pin_config.gpio_pin = p_cfg->pa_cfg.gpio_pin; - config.pa_pin_config.gpiote_ch_id = p_cfg->pa_gpiote_ch_id; + return result; +} + +nrf_802154_sl_ant_div_mode_t nrf_802154_antenna_diversity_tx_mode_get(void) +{ + return nrf_802154_sl_ant_div_cfg_mode_get(NRF_802154_SL_ANT_DIV_OP_TX); +} + +bool nrf_802154_antenna_diversity_rx_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna) +{ + bool result = + nrf_802154_sl_ant_div_cfg_antenna_set(NRF_802154_SL_ANT_DIV_OP_RX, antenna); + bool is_manual_mode = nrf_802154_sl_ant_div_cfg_mode_get(NRF_802154_SL_ANT_DIV_OP_RX) == + NRF_802154_SL_ANT_DIV_MODE_MANUAL; + + if (result && is_manual_mode) + { + nrf_802154_request_antenna_update(); + } - config.ppi_ch_id_set = p_cfg->ppi_ch_id_set; - config.ppi_ch_id_clr = p_cfg->ppi_ch_id_clr; + return result; +} - nrf_fem_interface_configuration_set(&config); +nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_rx_antenna_get(void) +{ + return nrf_802154_sl_ant_div_cfg_antenna_get(NRF_802154_SL_ANT_DIV_OP_RX); } -void nrf_802154_fem_control_cfg_get(nrf_802154_fem_control_cfg_t * p_cfg) +bool nrf_802154_antenna_diversity_tx_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna) { - nrf_fem_interface_config_t config; + bool result = + nrf_802154_sl_ant_div_cfg_antenna_set(NRF_802154_SL_ANT_DIV_OP_TX, antenna); + bool is_manual_mode = nrf_802154_sl_ant_div_cfg_mode_get(NRF_802154_SL_ANT_DIV_OP_TX) == + NRF_802154_SL_ANT_DIV_MODE_MANUAL; - nrf_fem_interface_configuration_get(&config); + if (result && is_manual_mode) + { + nrf_802154_request_antenna_update(); + } - p_cfg->lna_cfg.active_high = config.lna_pin_config.active_high; - p_cfg->lna_cfg.enable = config.lna_pin_config.enable; - p_cfg->lna_cfg.gpio_pin = config.lna_pin_config.gpio_pin; + return result; +} - p_cfg->pa_cfg.active_high = config.pa_pin_config.active_high; - p_cfg->pa_cfg.enable = config.pa_pin_config.enable; - p_cfg->pa_cfg.gpio_pin = config.pa_pin_config.gpio_pin; +nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_tx_antenna_get(void) +{ + return nrf_802154_sl_ant_div_cfg_antenna_get(NRF_802154_SL_ANT_DIV_OP_TX); +} - p_cfg->lna_gpiote_ch_id = config.lna_pin_config.gpiote_ch_id; - p_cfg->pa_gpiote_ch_id = config.pa_pin_config.gpiote_ch_id; +nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_last_rx_best_antenna_get(void) +{ + return nrf_802154_sl_ant_div_last_rx_best_antenna_get(); +} - p_cfg->ppi_ch_id_clr = config.ppi_ch_id_clr; - p_cfg->ppi_ch_id_set = config.ppi_ch_id_set; +void nrf_802154_antenna_diversity_config_set(const nrf_802154_sl_ant_div_cfg_t * p_cfg) +{ +#if defined(RADIO_INTENSET_SYNC_Msk) + nrf_802154_sl_ant_div_cfg_set(p_cfg); +#endif } -#endif // ENABLE_FEM +bool nrf_802154_antenna_diversity_config_get(nrf_802154_sl_ant_div_cfg_t * p_cfg) +{ + return nrf_802154_sl_ant_div_cfg_get(p_cfg); +} + +bool nrf_802154_antenna_diversity_init(void) +{ + return nrf_802154_sl_ant_div_init(); +} + +void nrf_802154_antenna_diversity_timer_irq_handler(void) +{ +#if defined(RADIO_INTENSET_SYNC_Msk) + nrf_802154_sl_ant_div_timer_irq_handle(); +#endif +} nrf_802154_state_t nrf_802154_state_get(void) { @@ -312,6 +365,9 @@ nrf_802154_state_t nrf_802154_state_get(void) case RADIO_STATE_CONTINUOUS_CARRIER: return NRF_802154_STATE_CONTINUOUS_CARRIER; + + case RADIO_STATE_MODULATED_CARRIER: + return NRF_802154_STATE_MODULATED_CARRIER; } return NRF_802154_STATE_INVALID; @@ -321,11 +377,12 @@ bool nrf_802154_sleep(void) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_SLEEP); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_request_sleep(NRF_802154_TERM_802154); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_SLEEP); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } @@ -333,13 +390,14 @@ nrf_802154_sleep_error_t nrf_802154_sleep_if_idle(void) { nrf_802154_sleep_error_t result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_SLEEP); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_request_sleep(NRF_802154_TERM_NONE) ? NRF_802154_SLEEP_ERROR_NONE : NRF_802154_SLEEP_ERROR_BUSY; - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_SLEEP); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } @@ -347,11 +405,11 @@ bool nrf_802154_receive(void) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RECEIVE); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_request_receive(NRF_802154_TERM_802154, REQ_ORIG_HIGHER_LAYER, NULL, true); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RECEIVE); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -360,7 +418,7 @@ bool nrf_802154_transmit_raw(const uint8_t * p_data, bool cca) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TRANSMIT); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_request_transmit(NRF_802154_TERM_NONE, REQ_ORIG_HIGHER_LAYER, @@ -369,7 +427,7 @@ bool nrf_802154_transmit_raw(const uint8_t * p_data, bool cca) false, NULL); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TRANSMIT); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -379,7 +437,7 @@ bool nrf_802154_transmit(const uint8_t * p_data, uint8_t length, bool cca) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TRANSMIT); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); tx_buffer_fill(p_data, length); result = nrf_802154_request_transmit(NRF_802154_TERM_NONE, @@ -389,12 +447,13 @@ bool nrf_802154_transmit(const uint8_t * p_data, uint8_t length, bool cca) false, NULL); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TRANSMIT); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } #endif // NRF_802154_USE_RAW_API +#if NRF_802154_DELAYED_TRX_ENABLED bool nrf_802154_transmit_raw_at(const uint8_t * p_data, bool cca, uint32_t t0, @@ -403,11 +462,11 @@ bool nrf_802154_transmit_raw_at(const uint8_t * p_data, { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TRANSMIT_AT); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_delayed_trx_transmit(p_data, cca, t0, dt, channel); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TRANSMIT_AT); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -415,11 +474,11 @@ bool nrf_802154_transmit_at_cancel(void) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TRANSMIT_AT_CANCEL); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_delayed_trx_transmit_cancel(); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TRANSMIT_AT_CANCEL); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -430,11 +489,11 @@ bool nrf_802154_receive_at(uint32_t t0, { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RECEIVE_AT); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_delayed_trx_receive(t0, dt, timeout, channel); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RECEIVE_AT); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -442,23 +501,25 @@ bool nrf_802154_receive_at_cancel(void) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RECEIVE_AT_CANCEL); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_delayed_trx_receive_cancel(); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RECEIVE_AT_CANCEL); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } +#endif // NRF_802154_DELAYED_TRX_ENABLED + bool nrf_802154_energy_detection(uint32_t time_us) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_ENERGY_DETECTION); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_request_energy_detection(NRF_802154_TERM_NONE, time_us); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_ENERGY_DETECTION); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -466,11 +527,11 @@ bool nrf_802154_cca(void) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CCA); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_request_cca(NRF_802154_TERM_NONE); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CCA); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -478,11 +539,23 @@ bool nrf_802154_continuous_carrier(void) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CONTINUOUS_CARRIER); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = nrf_802154_request_continuous_carrier(NRF_802154_TERM_NONE); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CONTINUOUS_CARRIER); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; +} + +bool nrf_802154_modulated_carrier(const uint8_t * p_data) +{ + bool result; + + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + result = nrf_802154_request_modulated_carrier(NRF_802154_TERM_NONE, p_data); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -490,34 +563,34 @@ bool nrf_802154_continuous_carrier(void) void nrf_802154_buffer_free_raw(uint8_t * p_data) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result; rx_buffer_t * p_buffer = (rx_buffer_t *)p_data; assert(p_buffer->free == false); (void)p_buffer; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_BUFFER_FREE); - result = nrf_802154_request_buffer_free(p_data); assert(result); (void)result; - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_BUFFER_FREE); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } bool nrf_802154_buffer_free_immediately_raw(uint8_t * p_data) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result; rx_buffer_t * p_buffer = (rx_buffer_t *)p_data; assert(p_buffer->free == false); (void)p_buffer; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_BUFFER_FREE); - result = nrf_802154_request_buffer_free(p_data); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_BUFFER_FREE); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -525,34 +598,34 @@ bool nrf_802154_buffer_free_immediately_raw(uint8_t * p_data) void nrf_802154_buffer_free(uint8_t * p_data) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result; rx_buffer_t * p_buffer = (rx_buffer_t *)(p_data - RAW_PAYLOAD_OFFSET); assert(p_buffer->free == false); (void)p_buffer; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_BUFFER_FREE); - result = nrf_802154_request_buffer_free(p_data - RAW_PAYLOAD_OFFSET); assert(result); (void)result; - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_BUFFER_FREE); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } bool nrf_802154_buffer_free_immediately(uint8_t * p_data) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result; rx_buffer_t * p_buffer = (rx_buffer_t *)(p_data - RAW_PAYLOAD_OFFSET); assert(p_buffer->free == false); (void)p_buffer; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_BUFFER_FREE); - result = nrf_802154_request_buffer_free(p_data - RAW_PAYLOAD_OFFSET); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_BUFFER_FREE); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -610,16 +683,18 @@ void nrf_802154_src_addr_matching_method_set(nrf_802154_src_addr_match_t match_m nrf_802154_ack_data_src_addr_matching_method_set(match_method); } -bool nrf_802154_ack_data_set(const uint8_t * p_addr, - bool extended, - const void * p_data, - uint16_t length, - uint8_t data_type) +bool 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) { return nrf_802154_ack_data_for_addr_set(p_addr, extended, data_type, p_data, length); } -bool nrf_802154_ack_data_clear(const uint8_t * p_addr, bool extended, uint8_t data_type) +bool nrf_802154_ack_data_clear(const uint8_t * p_addr, + bool extended, + nrf_802154_ack_data_t data_type) { return nrf_802154_ack_data_for_addr_clear(p_addr, extended, data_type); } @@ -665,27 +740,58 @@ void nrf_802154_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg) void nrf_802154_transmit_csma_ca_raw(const uint8_t * p_data) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CSMACA); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); nrf_802154_csma_ca_start(p_data); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CSMACA); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } #else // NRF_802154_USE_RAW_API void nrf_802154_transmit_csma_ca(const uint8_t * p_data, uint8_t length) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CSMACA); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); tx_buffer_fill(p_data, length); nrf_802154_csma_ca_start(m_tx_buffer); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CSMACA); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } #endif // NRF_802154_USE_RAW_API + +bool nrf_802154_csma_ca_min_be_set(uint8_t min_be) +{ + return nrf_802154_pib_csmaca_min_be_set(min_be); +} + +uint8_t nrf_802154_csma_ca_min_be_get(void) +{ + return nrf_802154_pib_csmaca_min_be_get(); +} + +bool nrf_802154_csma_ca_max_be_set(uint8_t max_be) +{ + return nrf_802154_pib_csmaca_max_be_set(max_be); +} + +uint8_t nrf_802154_csma_ca_max_be_get(void) +{ + return nrf_802154_pib_csmaca_max_be_get(); +} + +void nrf_802154_csma_ca_max_backoffs_set(uint8_t max_backoffs) +{ + nrf_802154_pib_csmaca_max_backoffs_set(max_backoffs); +} + +uint8_t nrf_802154_csma_ca_max_backoffs_get(void) +{ + return nrf_802154_pib_csmaca_max_backoffs_get(); +} + #endif // NRF_802154_CSMA_CA_ENABLED #if NRF_802154_ACK_TIMEOUT_ENABLED @@ -697,6 +803,45 @@ void nrf_802154_ack_timeout_set(uint32_t time) #endif // NRF_802154_ACK_TIMEOUT_ENABLED +#if NRF_802154_IFS_ENABLED + +nrf_802154_ifs_mode_t nrf_802154_ifs_mode_get(void) +{ + return nrf_802154_pib_ifs_mode_get(); +} + +bool nrf_802154_ifs_mode_set(nrf_802154_ifs_mode_t mode) +{ + return nrf_802154_pib_ifs_mode_set(mode); +} + +uint16_t nrf_802154_ifs_min_sifs_period_get(void) +{ + return nrf_802154_pib_ifs_min_sifs_period_get(); +} + +void nrf_802154_ifs_min_sifs_period_set(uint16_t period) +{ + nrf_802154_pib_ifs_min_sifs_period_set(period); +} + +uint16_t nrf_802154_ifs_min_lifs_period_get(void) +{ + return nrf_802154_pib_ifs_min_lifs_period_get(); +} + +void nrf_802154_ifs_min_lifs_period_set(uint16_t period) +{ + nrf_802154_pib_ifs_min_lifs_period_set(period); +} + +#endif // NRF_802154_IFS_ENABLED + +uint32_t nrf_802154_time_get(void) +{ + return nrf_802154_timer_sched_time_get(); +} + __WEAK void nrf_802154_tx_ack_started(const uint8_t * p_data) { (void)p_data; @@ -705,7 +850,8 @@ __WEAK void nrf_802154_tx_ack_started(const uint8_t * p_data) #if NRF_802154_USE_RAW_API __WEAK void nrf_802154_received_raw(uint8_t * p_data, int8_t power, uint8_t lqi) { - nrf_802154_received_timestamp_raw(p_data, power, lqi, last_rx_frame_timestamp_get()); + nrf_802154_received_timestamp_raw(p_data, power, lqi, + nrf_802154_stat_timestamp_read(last_rx_end_timestamp)); } __WEAK void nrf_802154_received_timestamp_raw(uint8_t * p_data, @@ -759,7 +905,8 @@ __WEAK void nrf_802154_transmitted_raw(const uint8_t * p_frame, int8_t power, uint8_t lqi) { - uint32_t timestamp = (p_ack == NULL) ? NRF_802154_NO_TIMESTAMP : last_rx_frame_timestamp_get(); + uint32_t timestamp = (p_ack == NULL) ? NRF_802154_NO_TIMESTAMP : nrf_802154_stat_timestamp_read( + last_ack_end_timestamp); nrf_802154_transmitted_timestamp_raw(p_frame, p_ack, power, lqi, timestamp); } diff --git a/src/nrf_802154.h b/src/nrf_802154.h index 6a45739..63c54a1 100644 --- a/src/nrf_802154.h +++ b/src/nrf_802154.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -43,11 +44,7 @@ #include "nrf_802154_config.h" #include "nrf_802154_types.h" -#include "nrf_ppi.h" - -#if ENABLE_FEM -#include "fem/nrf_fem_protocol_api.h" -#endif +#include "nrf_802154_sl_ant_div.h" #ifdef __cplusplus extern "C" { @@ -64,6 +61,7 @@ extern "C" { * This function initializes the RADIO peripheral in the @ref RADIO_STATE_SLEEP state. * * @note This function is to be called once, before any other functions from this module. + * Only the functions setting the configuration can be called before this call. */ void nrf_802154_init(void); @@ -88,6 +86,20 @@ void nrf_802154_deinit(void); void nrf_802154_radio_irq_handler(void); #endif // !NRF_802154_INTERNAL_RADIO_IRQ_HANDLING +#if !NRF_802154_INTERNAL_SWI_IRQ_HANDLING +/** + * @brief Handles the interrupt request from the RADIO peripheral. + * + * @note If NRF_802154_INTERNAL_SWI_IRQ_HANDLING is enabled, the driver internally handles the + * SWI IRQ, and this function must not be called. + * + * This function is intended for use in an operating system environment, where the OS handles IRQ + * and indirectly passes it to the driver, or with a RAAL implementation that indirectly passes + * radio IRQ to the driver (that is, SoftDevice). + */ +void nrf_802154_swi_irq_handler(void); +#endif // !NRF_802154_INTERNAL_SWI_IRQ_HANDLING + /** * @brief Sets the channel on which the radio is to operate. * @@ -119,60 +131,177 @@ void nrf_802154_tx_power_set(int8_t power); */ int8_t nrf_802154_tx_power_get(void); -#if ENABLE_FEM +/** + * @brief Sets the antenna diversity rx mode. + * + * @note This function should not be called while reception or transmission are currently ongoing. + * + * @param[in] mode Antenna diversity rx mode to be set. + * + * @retval true Antenna diversity rx mode set successfully. + * @retval false Invalid mode passed as argument. + */ +bool nrf_802154_antenna_diversity_rx_mode_set(nrf_802154_sl_ant_div_mode_t mode); /** - * @defgroup nrf_802154_frontend Frontend Module management - * @{ + * @brief Gets current antenna diversity rx mode. + * + * @return Current antenna diversity mode for rx. */ +nrf_802154_sl_ant_div_mode_t nrf_802154_antenna_diversity_rx_mode_get(void); -/** Structure that contains the run-time configuration of the Frontend Module. */ -typedef nrf_fem_control_cfg_t nrf_802154_fem_control_cfg_t; +/** + * @brief Sets the antenna diversity tx mode. + * + * @note This function should not be called while reception or transmission are currently ongoing. + * @note NRF_802154_SL_ANT_DIV_MODE_AUTO is not supported for transmission. + * + * @param[in] mode Antenna diversity tx mode to be set. + * + * @retval true Antenna diversity tx mode set successfully. + * @retval false Invalid mode passed as argument. + */ +bool nrf_802154_antenna_diversity_tx_mode_set(nrf_802154_sl_ant_div_mode_t mode); -/** Macro with the default configuration of the Frontend Module. */ -#define NRF_802154_FEM_DEFAULT_SETTINGS \ - ((nrf_802154_fem_control_cfg_t) { \ - .pa_cfg = { \ - .enable = 1, \ - .active_high = 1, \ - .gpio_pin = NRF_FEM_CONTROL_DEFAULT_PA_PIN, \ - }, \ - .lna_cfg = { \ - .enable = 1, \ - .active_high = 1, \ - .gpio_pin = NRF_FEM_CONTROL_DEFAULT_LNA_PIN, \ - }, \ - .pa_gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_PA_GPIOTE_CHANNEL, \ - .lna_gpiote_ch_id = NRF_FEM_CONTROL_DEFAULT_LNA_GPIOTE_CHANNEL, \ - .ppi_ch_id_set = NRF_FEM_CONTROL_DEFAULT_SET_PPI_CHANNEL, \ - .ppi_ch_id_clr = NRF_FEM_CONTROL_DEFAULT_CLR_PPI_CHANNEL, \ - }) +/** + * @brief Gets current antenna diversity tx mode. + * + * @return Current antenna diversity mode for tx. + */ +nrf_802154_sl_ant_div_mode_t nrf_802154_antenna_diversity_tx_mode_get(void); + +/** + * @brief Manually selects the antenna to be used for rx. + * + * For antenna to be switched, antenna diversity rx mode needs + * to be @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise, antenna will + * be only switched after @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL is set. + * + * @param[in] antenna Antenna to be used. + * + * @retval true Antenna set successfully. + * @retval false Invalid antenna passed as argument. + */ +bool nrf_802154_antenna_diversity_rx_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna); + +/** + * @brief Gets antenna currently used for rx. + * + * @note The antenna read by this function is currently used rx antenna only if + * antenna diversity rx mode is set to @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise, + * currently used antenna may be different. + * @sa nrf_802154_sl_ant_div_mode_set + * + * @return Currently used antenna. + */ +nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_rx_antenna_get(void); + +/** + * @brief Manually selects the antenna to be used for tx. + * + * For antenna to be switched, antenna diversity tx mode needs + * to be @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise, antenna will + * be only switched after @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL is set. + * + * @param[in] antenna Antenna to be used. + * + * @retval true Antenna set successfully. + * @retval false Invalid antenna passed as argument. + */ +bool nrf_802154_antenna_diversity_tx_antenna_set(nrf_802154_sl_ant_div_antenna_t antenna); + +/** + * @brief Gets antenna currently used for tx. + * + * @note The antenna read by this function is currently used tx antenna only if + * antenna diversity tx mode is set to @ref NRF_802154_SL_ANT_DIV_MODE_MANUAL. Otherwise, + * currently used antenna may be different. + * @sa nrf_802154_sl_ant_div_mode_set + * + * @return Currently used antenna. + */ +nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_tx_antenna_get(void); + +/** + * @brief Gets which antenna was selected as best for the last reception. + * + * @note In three cases @ref NRF_802154_SL_ANT_DIV_ANTENNA_NONE may be returned: + * - No frame was received yet. + * - Last frame was received with antenna diversity auto mode disabled. + * - RSSI measurements didn't have enough time to finish during last frame reception + * and it is unspecified which antenna was selected. + * + * @return Antenna selected during last successful reception in automatic mode. + */ +nrf_802154_sl_ant_div_antenna_t nrf_802154_antenna_diversity_last_rx_best_antenna_get(void); /** - * @brief Sets the PA & LNA GPIO toggle configuration. + * @brief Sets antenna diversity configuration. + * + * @note If antenna diversity feature is to be used, this function must be called before + * @ref nrf_802154_antenna_diversity_init. * - * @note This function must not be called when the radio is in use. + * @note This function must be called only once. * - * @note This function is deprecated. Only to be used with Skyworks module. - * Consider using nrf_fem_interface_configuration_set instead. + * @param[in] p_cfg Pointer to antenna diversity interface configuration. + */ +void nrf_802154_antenna_diversity_config_set(const nrf_802154_sl_ant_div_cfg_t * p_cfg); + +/** + * @brief Gets the antenna diversity interface configuration. * - * @param[in] p_cfg Pointer to the PA & LNA GPIO toggle configuration. + * @param[out] p_cfg Antenna diversity interface configuration. * + * @retval true The configuration was retrieved successfully. + * @retval false The configuration could not be retrieved. */ -void nrf_802154_fem_control_cfg_set(nrf_802154_fem_control_cfg_t const * const p_cfg); +bool nrf_802154_antenna_diversity_config_get(nrf_802154_sl_ant_div_cfg_t * p_cfg); /** - * @brief Get the PA & LNA GPIO toggle configuration. + * @brief Initializes antenna diversity module. * - * @param[out] p_cfg Pointer to the structure for the PA & LNA GPIO toggle configuration. + * This function should be called before starting radio operations, but at any time + * after driver initialization. In order for it to succeed, antenna diversity interface + * configuration must be provided before it's called with + * @ref nrf_802154_antenna_diversity_config_set. Example usage: * - * @note This function is deprecated. Only to be used with Skyworks module. - * Consider using nrf_fem_interface_configuration_get instead. + * @code + * nrf_802154_init(); + * + * nrf_802154_sl_ant_div_cfg_t cfg = + * { + * // Set the configuration parameters accordingly + * }; + * + * nrf_802154_antenna_config_set(&cfg); + * nrf_802154_antenna_diversity_init(); + * + * // At any later time + * nrf_802154_receive(); + * @endcode + * + * @retval true Initialization was successful. + * @retval false Initialization could not be performed due to unconfigured interface. + */ +bool nrf_802154_antenna_diversity_init(void); + +/** + * @brief Handles TIMER IRQ of the antenna diversity interface. * + * This function should be called when the timer instance provided to the antenna diversity + * interface reports an interrupt. */ -void nrf_802154_fem_control_cfg_get(nrf_802154_fem_control_cfg_t * p_cfg); +void nrf_802154_antenna_diversity_timer_irq_handler(void); -#endif // ENABLE_FEM +/** + * @brief Gets the current time. + * + * The time returned by this function is to be used to calculate timing parameters for + * @ref nrf_802154_transmit_at and @ref nrf_802154_receive_at functions. + * + * @returns Current time in microseconds. + */ +uint32_t nrf_802154_time_get(void); /** * @} @@ -524,6 +653,20 @@ bool nrf_802154_cca(void); */ bool nrf_802154_continuous_carrier(void); +/** + * @brief Changes the radio state to modulated carrier. + * + * @note When the radio is emitting modulated carrier signals, it blocks all transmissions on the + * selected channel. This function is to be called only during radio tests. Do not + * use it during normal device operation. + * + * @param[in] p_data Pointer to a buffer to modulate the carrier with. + * + * @retval true The modulated carrier procedure was scheduled. + * @retval false The driver could not schedule the modulated carrier procedure. + */ +bool nrf_802154_modulated_carrier(const uint8_t * p_data); + /** * @} * @defgroup nrf_802154_calls Calls to higher layer @@ -1036,11 +1179,11 @@ void nrf_802154_src_addr_matching_method_set(nrf_802154_src_addr_match_t match_m * @retval True Address successfully added to the list. * @retval False Not enough memory to store this address in the list. */ -bool nrf_802154_ack_data_set(const uint8_t * p_addr, - bool extended, - const void * p_data, - uint16_t length, - uint8_t data_type); +bool 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); /** * @brief Removes the address of a peer node for which the ACK data is set from the pending bit list. @@ -1063,7 +1206,9 @@ bool nrf_802154_ack_data_set(const uint8_t * p_addr, * @retval True Address removed from the list. * @retval False Address not found in the list. */ -bool nrf_802154_ack_data_clear(const uint8_t * p_addr, bool extended, uint8_t data_type); +bool nrf_802154_ack_data_clear(const uint8_t * p_addr, + bool extended, + nrf_802154_ack_data_t data_type); /** * @brief Enables or disables setting a pending bit in automatically transmitted ACK frames. @@ -1214,6 +1359,57 @@ void nrf_802154_transmit_csma_ca_raw(const uint8_t * p_data); void nrf_802154_transmit_csma_ca(const uint8_t * p_data, uint8_t length); #endif // NRF_802154_USE_RAW_API + +/** + * @brief Sets the minimum value of the backoff exponent (BE) in the CSMA-CA algorithm. + * + * @param[in] min_be Minimum value of the backoff exponent. + * + * @retval true When value provided by @p min_be has been set successfully. + * @retval false Otherwise. + */ +bool nrf_802154_csma_ca_min_be_set(uint8_t min_be); + +/** + * @brief Gets the minimum value of the backoff exponent (BE) in the CSMA-CA algorithm. + * + * @return Current minimum value of the backoff exponent. + */ +uint8_t nrf_802154_csma_ca_min_be_get(void); + +/** + * @brief Sets the maximum value of the backoff exponent (BE) in the CSMA-CA algorithm. + * + * @param[in] max_be Maximum value of the backoff exponent. + * + * @retval true When value provided by @p max_be has been set successfully. + * @retval false Otherwise. + */ +bool nrf_802154_csma_ca_max_be_set(uint8_t max_be); + +/** + * @brief Gets the maximum value of the backoff exponent (BE) in the CSMA-CA algorithm. + * + * @return Current maximum value of the backoff exponent. + */ +uint8_t nrf_802154_csma_ca_max_be_get(void); + +/** + * @brief Sets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring + * a channel access failure. + * + * @param[in] max_backoffs Maximum number of backoffs. + */ +void nrf_802154_csma_ca_max_backoffs_set(uint8_t max_backoffs); + +/** + * @brief Gets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring + * a channel access failure. + * + * @return Current maximum number of backoffs. + */ +uint8_t nrf_802154_csma_ca_max_backoffs_get(void); + #endif // NRF_802154_CSMA_CA_ENABLED /** @@ -1235,6 +1431,194 @@ void nrf_802154_ack_timeout_set(uint32_t time); #endif // NRF_802154_ACK_TIMEOUT_ENABLED +/** + * @} + * @defgroup nrf_802154_coex Wifi Coex feature + * @{ + */ + +/** + * @brief Enables wifi coex signaling. + * + * When @ref nrf_802154_init is called, the wifi coex signaling is initially enabled or disabled + * depending on @ref NRF_802154_COEX_INITIALLY_ENABLED. You can call this function + * (after @ref nrf_802154_init) to enable the wifi coex signaling. When wifi coex signaling + * has been already enabled, this function has no effect. + * + * When this function is called during receive or transmit operation, the effect on coex interface + * may be delayed until current frame (or ack) is received or transmitted. + * To avoid this issue please call this function when the driver is in sleep mode. + * + * @retval true Wifi coex is supported and is enabled after call to this function. + * @retval false Wifi coex is not supported. + */ +bool nrf_802154_wifi_coex_enable(void); + +/** + * @brief Disables wifi coex signaling. + * + * You can call this function (after @ref nrf_802154_init) to disable the wifi coex signaling. + * When wifi coex signaling has been already disabled, this function has no effect. + * + * When this function is called during receive or transmit operation, the effect on coex interface + * may be delayed until current frame (or ack) is received or transmitted. + * To avoid this issue please call this function when the driver is in sleep mode. + */ +void nrf_802154_wifi_coex_disable(void); + +/** + * @brief Checks if wifi coex signaling is enabled. + * + * @retval true Wifi coex signaling is enabled. + * @retval false Wifi coex signaling is disabled. + */ +bool nrf_802154_wifi_coex_is_enabled(void); + +/** + * @brief Sets Coex request mode used in receive operations. + * + * @param[in] mode Coex receive request mode. For allowed values see @ref nrf_802154_coex_rx_request_mode_t type. + * + * @retval true Operation succeeded. + * @retval false Requested mode is not supported. + */ +bool nrf_802154_coex_rx_request_mode_set(nrf_802154_coex_rx_request_mode_t mode); + +/** + * @brief Gets Coex request mode used in receive operations. + * + * @return Current Coex receive request mode. For allowed values see @ref nrf_802154_coex_rx_request_mode_t type. + */ +nrf_802154_coex_rx_request_mode_t nrf_802154_coex_rx_request_mode_get(void); + +/** + * @brief Sets Coex request mode used in transmit operations. + * + * @param[in] mode Coex transmit request mode. For allowed values see @ref nrf_802154_coex_tx_request_mode_t type. + * + * @retval true Operation succeeded. + * @retval false Requested mode is not supported. + */ +bool nrf_802154_coex_tx_request_mode_set(nrf_802154_coex_tx_request_mode_t mode); + +/** + * @brief Gets Coex request mode used in transmit operations. + * + * @return Current Coex transmit request mode. For allowed values see @ref nrf_802154_coex_tx_request_mode_t type. + */ +nrf_802154_coex_tx_request_mode_t nrf_802154_coex_tx_request_mode_get(void); + +/** + * @} + * @defgroup nrf_802154_stats Statistics and measurements + * @{ + */ + +/** + * @brief Gets current statistics. + * + * @param[out] p_stats Structure that will be filled with current stats values. + */ +void nrf_802154_stats_get(nrf_802154_stats_t * p_stats); + +/** + * @brief Get current statistics. + * + * @note This returns part of information returned by @ref nrf_802154_stats_get + * + * @param[out] p_stat_counters Structure that will be filled with current stats counter values. + */ +void nrf_802154_stat_counters_get(nrf_802154_stat_counters_t * p_stat_counters); + +/** + * @brief Decreases current statistic counter values by the provided ones. + * + * This function is intended to be called together with @ref nrf_802154_stats_get + * to avoid missing any counted events. + * + * @param[in] p_stat_counters Current stat counter values will be decreased by values provided + * behind this pointer. + */ +void nrf_802154_stat_counters_subtract(const nrf_802154_stat_counters_t * p_stat_counters); + +/** + * @brief Get time stamps of events gathered by the last operation. + * + * @param[out] p_stat_timestamps Structure that will be filled with current time stamps of events. + */ +void nrf_802154_stat_timestamps_get(nrf_802154_stat_timestamps_t * p_stat_timestamps); + +/** + * @brief Resets current stat counters to 0. + * + * @note @ref nrf_802154_stat_counters_get and @ref nrf_802154_stat_counters_reset may lead to + * missing events if an counted event occurs between these calls. Use + * @ref nrf_802154_stat_counters_subtract to avoid such condition if necessary. + */ +void nrf_802154_stat_counters_reset(void); + +/** + * @brief Get total times spent in certain states. + * + * @param[out] p_stat_totals Structure that will be filled with times spent in certain states + * until now. + */ +void nrf_802154_stat_totals_get(nrf_802154_stat_totals_t * p_stat_totals); + +/** + * @} + * @defgroup nrf_802154_ifs Inter-frame spacing feature + * @{ + */ +#if NRF_802154_IFS_ENABLED + +/** + * @brief Gets IFS operation mode. + * + * @return Current IFS operation mode. Refer to @ref nrf_802154_ifs_mode_t for details. + */ +nrf_802154_ifs_mode_t nrf_802154_ifs_mode_get(void); + +/** + * @brief Sets IFS operation mode. + * + * @param[in] mode IFS operation mode. Refer to @ref nrf_802154_ifs_mode_t for details. + * + * @retval true The update of IFS operation mode was successful. + * @retval false The update of IFS operation mode failed. Provided mode is unsupported + */ +bool nrf_802154_ifs_mode_set(nrf_802154_ifs_mode_t mode); + +/** + * @brief Gets Short IFS period in microseconds. + * + * @return Current Short IFS period in microseconds. + */ +uint16_t nrf_802154_ifs_min_sifs_period_get(void); + +/** + * @brief Sets Short IFS period in microseconds. + * + * @param[in] period Short IFS period in microseconds. + */ +void nrf_802154_ifs_min_sifs_period_set(uint16_t period); + +/** + * @brief Gets Long IFS period in microseconds. + * + * @return Current Long IFS period in microseconds. + */ +uint16_t nrf_802154_ifs_min_lifs_period_get(void); + +/** + * @brief Sets Long IFS period in microseconds. + * + * @param[in] period Long IFS period in microseconds. + */ +void nrf_802154_ifs_min_lifs_period_set(uint16_t period); + +#endif // NRF_802154_IFS_ENABLED + /** @} */ #ifdef __cplusplus diff --git a/src/nrf_802154_config.h b/src/nrf_802154_config.h index ecc95fd..13e1874 100644 --- a/src/nrf_802154_config.h +++ b/src/nrf_802154_config.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_CONFIG_H__ @@ -113,6 +114,26 @@ extern "C" { #endif // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING +/** + * @def NRF_802154_INTERNAL_SWI_IRQ_HANDLING + * + * If the driver is expected to internally handle the SWI IRQ. + * If the driver is used in an OS, the SWI IRQ can be handled by the OS and passed to + * the driver by @ref nrf_802154_swi_irq_handler. + * In this case, the internal handling must be disabled. + * + */ + +#ifndef NRF_802154_INTERNAL_SWI_IRQ_HANDLING + +#if RAAL_SOFTDEVICE || RAAL_REM +#define NRF_802154_INTERNAL_SWI_IRQ_HANDLING 0 +#else // RAAL_SOFTDEVICE || RAAL_REM +#define NRF_802154_INTERNAL_SWI_IRQ_HANDLING 1 +#endif // RAAL_SOFTDEVICE || RAAL_REM + +#endif // NRF_802154_INTERNAL_SWI_IRQ_HANDLING + /** * @def NRF_802154_IRQ_PRIORITY * @@ -131,7 +152,7 @@ extern "C" { * */ #ifndef NRF_802154_SWI_PRIORITY -#define NRF_802154_SWI_PRIORITY 5 +#define NRF_802154_SWI_PRIORITY 4 #endif /** @@ -185,6 +206,9 @@ extern "C" { * during the frame reception. With this flag set to 1, the address filtering is done after * receiving a frame, during NRF_RADIO_EVENT_END handling. * + * @note This option is incompatible with antenna diversity. If set to 1, antenna diversity + * must not be used. + * */ #ifndef NRF_802154_DISABLE_BCC_MATCHING #define NRF_802154_DISABLE_BCC_MATCHING 0 @@ -208,6 +232,7 @@ extern "C" { * Enabling this feature enables the functions @ref nrf_802154_received_timestamp_raw, * @ref nrf_802154_received_timestamp, @ref nrf_802154_transmitted_timestamp_raw, and * @ref nrf_802154_transmitted_timestamp, which add timestamps to the frames received. + * This option also enables timestamping in stats. * */ #ifndef NRF_802154_FRAME_TIMESTAMP_ENABLED @@ -215,64 +240,26 @@ extern "C" { #endif /** - * @def NRF_802154_DELAYED_TRX_ENABLED + * @def NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED * - * If the delayed transmission and the receive window features are available. + * If measurement of total time spent in certain states is to be calculated. * + * This option can be enabled when @ref NRF_802154_FRAME_TIMESTAMP_ENABLED is 1 + * and @ref NRF_802154_DISABLE_BCC_MATCHING is 0. */ -#ifndef NRF_802154_DELAYED_TRX_ENABLED -#define NRF_802154_DELAYED_TRX_ENABLED 1 +#ifndef NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED +#define NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED \ + (1 && NRF_802154_FRAME_TIMESTAMP_ENABLED && !NRF_802154_DISABLE_BCC_MATCHING) #endif /** - * @} - * @defgroup nrf_802154_config_clock Clock driver configuration - * @{ - */ - -/** - * @def NRF_802154_CLOCK_IRQ_PRIORITY - * - * The priority of clock interrupt used in the standalone clock driver implementation. - * - * @note This configuration is only applicable for the Clock Abstraction Layer implementation - * in nrf_802154_clock_nodrv.c. - * - */ -#ifndef NRF_802154_CLOCK_IRQ_PRIORITY -#define NRF_802154_CLOCK_IRQ_PRIORITY 7 -#endif - -/** - * @def NRF_802154_CLOCK_LFCLK_SOURCE - * - * The low-frequency clock source used in the standalone clock driver implementation. - * - * @note This configuration is only applicable for the Clock Abstraction Layer implementation - * in nrf_802154_clock_nodrv.c. - * - */ -#ifndef NRF_802154_CLOCK_LFCLK_SOURCE -#define NRF_802154_CLOCK_LFCLK_SOURCE NRF_CLOCK_LFCLK_Xtal -#endif - -/** - * @} - * @defgroup nrf_802154_config_rtc RTC driver configuration - * @{ - */ - -/** - * @def NRF_802154_RTC_IRQ_PRIORITY - * - * The priority of RTC interrupt used in the standalone timer driver implementation. + * @def NRF_802154_DELAYED_TRX_ENABLED * - * @note This configuration is only applicable for the Low Power Timer Abstraction Layer - * implementation in nrf_802154_lp_timer.c. + * If the delayed transmission and the receive window features are available. * */ -#ifndef NRF_802154_RTC_IRQ_PRIORITY -#define NRF_802154_RTC_IRQ_PRIORITY 6 +#ifndef NRF_802154_DELAYED_TRX_ENABLED +#define NRF_802154_DELAYED_TRX_ENABLED 1 #endif /** @@ -293,36 +280,55 @@ extern "C" { #endif /** - * @def NRF_802154_CSMA_CA_MIN_BE + * @def NRF_802154_CSMA_CA_MIN_BE_DEFAULT * - * The minimum value of the backoff exponent (BE) in the CSMA-CA algorithm + * The default minimum value of the backoff exponent (BE) in the CSMA-CA algorithm * (see IEEE 802.15.4-2015: 6.2.5.1). * + * @note The minimum value of the backoff exponent may be changed from default by calling the + * @ref nrf_802154_pib_csmaca_min_be_set function. + * */ -#ifndef NRF_802154_CSMA_CA_MIN_BE -#define NRF_802154_CSMA_CA_MIN_BE 3 +#ifdef NRF_802154_CSMA_CA_MIN_BE +#error "NRF_802154_CSMA_CA_MIN_BE was replaced with NRF_802154_CSMA_CA_MIN_BE_DEFAULT" +#endif +#ifndef NRF_802154_CSMA_CA_MIN_BE_DEFAULT +#define NRF_802154_CSMA_CA_MIN_BE_DEFAULT 3 #endif /** - * @def NRF_802154_CSMA_CA_MAX_BE + * @def NRF_802154_CSMA_CA_MAX_BE_DEFAULT * - * The maximum value of the backoff exponent, BE, in the CSMA-CA algorithm + * The default maximum value of the backoff exponent, BE, in the CSMA-CA algorithm * (see IEEE 802.15.4-2015: 6.2.5.1). * + * @note The maximum value of the backoff exponent may be changed from default by calling the + * @ref nrf_802154_pib_csmaca_max_be_set function. + * */ -#ifndef NRF_802154_CSMA_CA_MAX_BE -#define NRF_802154_CSMA_CA_MAX_BE 5 +#ifdef NRF_802154_CSMA_CA_MAX_BE +#error "NRF_802154_CSMA_CA_MAX_BE was replaced with NRF_802154_CSMA_CA_MAX_BE_DEFAULT" +#endif +#ifndef NRF_802154_CSMA_CA_MAX_BE_DEFAULT +#define NRF_802154_CSMA_CA_MAX_BE_DEFAULT 5 #endif /** - * @def NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS + * @def NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS_DEFAULT * - * The maximum number of backoffs that the CSMA-CA algorithm will attempt before declaring a channel - * access failure. + * The default maximum number of backoffs that the CSMA-CA algorithm will attempt before declaring + * a channel access failure. + * + * @note The maximum number of backoffs may be changed from default by calling the + * @ref nrf_802154_pib_csmaca_max_backoffs_set function. * */ -#ifndef NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS -#define NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS 4 +#ifdef NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS_DEFAULT +#error \ + "NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS was replaced with NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS_DEFAULT" +#endif +#ifndef NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS_DEFAULT +#define NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS_DEFAULT 4 #endif /** @@ -388,6 +394,22 @@ extern "C" { #define NRF_802154_MAX_ACK_IE_SIZE 8 #endif +/** + * @} + * @defgroup nrf_802154_config_ifs Interframe spacing feature configuration + * @{ + */ + +/** + * @def NRF_802154_IFS_ENABLED + * + * Indicates whether the Short/Long Interframe spacing feature is to be enabled in the driver. + * + */ +#ifndef NRF_802154_IFS_ENABLED +#define NRF_802154_IFS_ENABLED 1 +#endif + /** * @} * @defgroup nrf_802154_config_transmission Transmission start notification feature configuration @@ -411,8 +433,51 @@ extern "C" { #endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED /** - *@} - **/ + * @} + * @defgroup nrf_802154_coex WiFi coexistence feature configuration + * @{ + */ + +/** + * @def NRF_802154_COEX_INITIALLY_ENABLED + * + * Configures if WiFi coex is initially enabled or disabled. + */ +#ifndef NRF_802154_COEX_INITIALLY_ENABLED +#define NRF_802154_COEX_INITIALLY_ENABLED 1 +#endif + +/** + * @} + * @defgroup nrf_802154_stats Statistics configuration + * @{ + */ + +/** + * @def NRF_802154_STATS_COUNT_ENERGY_DETECTED_EVENTS + * + * Configures if energy detected events will be counted in receive mode. + * When this option is enabled additional interrupts on energy detected events will occur + * increasing power consumption. The events counter is stored in + * @ref nrf_802154_stat_counters_t::received_energy_events field and can be retrieved by + * a call to @ref nrf_802154_stats_get or @ref nrf_802154_stat_counters_get. + */ +#ifndef NRF_802154_STATS_COUNT_ENERGY_DETECTED_EVENTS +#define NRF_802154_STATS_COUNT_ENERGY_DETECTED_EVENTS 1 +#endif + +/** + * @def NRF_802154_STATS_COUNT_RECEIVED_PREAMBLES + * + * Configures if number of received preambles will be counted in receive mode. + * When this option is enabled additional interrupts on preamble reveived will occur + * increasing power consumption. The events counter is stored in + * @ref nrf_802154_stat_counters_t::received_preambles field and can be retrieved by + * a call to @ref nrf_802154_stats_get or @ref nrf_802154_stat_counters_get. + */ +#ifndef NRF_802154_STATS_COUNT_RECEIVED_PREAMBLES +#define NRF_802154_STATS_COUNT_RECEIVED_PREAMBLES 1 +#endif #ifdef __cplusplus } diff --git a/src/nrf_802154_const.h b/src/nrf_802154_const.h index bc324ae..96593ce 100644 --- a/src/nrf_802154_const.h +++ b/src/nrf_802154_const.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -152,12 +153,14 @@ #define PHY_SYMBOLS_PER_OCTET 2 ///< Number of symbols in a single byte (octet). #define PHY_SHR_SYMBOLS 10 ///< Number of symbols in the Synchronization Header (SHR). -#define ED_MIN_DBM (-94) ///< dBm value corresponding to value 0 in the EDSAMPLE register. -#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral. #define ED_RESULT_MAX 0xff ///< Maximal ED result. #define BROADCAST_ADDRESS ((uint8_t[SHORT_ADDRESS_SIZE]) {0xff, 0xff}) ///< Broadcast short address. +#define MIN_SIFS_PERIOD_US 192 ///< Minimum Short IFS period default value in us. +#define MIN_LIFS_PERIOD_US 640 ///< Minimum Long IFS period default value in us. +#define MAX_SIFS_FRAME_SIZE 18 ///< Maximum frame length which can be followed by the Short Interframe Space. + typedef enum { REQ_ORIG_HIGHER_LAYER, @@ -172,6 +175,9 @@ typedef enum #if NRF_802154_DELAYED_TRX_ENABLED REQ_ORIG_DELAYED_TRX, #endif // NRF_802154_DELAYED_TRX_ENABLED +#if NRF_802154_IFS_ENABLED + REQ_ORIG_IFS, +#endif // NRF_802154_IFS_ENABLED } req_originator_t; -#endif // NRD_DRV_RADIO802154_CONST_H_ +#endif // NRF_802154_CONST_H_ diff --git a/src/nrf_802154_core.c b/src/nrf_802154_core.c index 53a369a..56ad254 100644 --- a/src/nrf_802154_core.c +++ b/src/nrf_802154_core.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -34,6 +35,8 @@ * */ +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_CORE + #include "nrf_802154_core.h" #include @@ -47,20 +50,19 @@ #include "nrf_802154_critical_section.h" #include "nrf_802154_debug.h" #include "nrf_802154_notification.h" +#include "nrf_802154_nrfx_addons.h" #include "nrf_802154_peripherals.h" #include "nrf_802154_pib.h" #include "nrf_802154_procedures_duration.h" #include "nrf_802154_rssi.h" #include "nrf_802154_rx_buffer.h" +#include "nrf_802154_stats.h" #include "nrf_802154_utils.h" -#include "nrf_802154_timer_coord.h" +#include "nrf_802154_trx.h" #include "nrf_802154_types.h" #include "nrf_802154_utils.h" -#include "nrf_egu.h" -#include "nrf_error.h" -#include "nrf_ppi.h" -#include "nrf_radio.h" -#include "nrf_timer.h" +#include "drivers/nrfx_errors.h" +#include "hal/nrf_radio.h" #include "fem/nrf_fem_protocol_api.h" #include "mac_features/nrf_802154_delayed_trx.h" #include "mac_features/nrf_802154_filter.h" @@ -69,92 +71,38 @@ #include "mac_features/ack_generator/nrf_802154_ack_generator.h" #include "rsch/nrf_802154_rsch.h" #include "rsch/nrf_802154_rsch_crit_sect.h" +#include "timer/nrf_802154_timer_coord.h" +#include "timer/nrf_802154_timer_sched.h" +#include "platform/hp_timer/nrf_802154_hp_timer.h" #include "platform/irq/nrf_802154_irq.h" #include "nrf_802154_core_hooks.h" - -#define EGU_EVENT NRF_EGU_EVENT_TRIGGERED15 -#define EGU_TASK NRF_EGU_TASK_TRIGGER15 -#define PPI_CHGRP0 NRF_802154_PPI_CORE_GROUP ///< PPI group used to disable self-disabling PPIs -#define PPI_CHGRP0_DIS_TASK NRF_PPI_TASK_CHG0_DIS ///< PPI task used to disable self-disabling PPIs - -#define PPI_DISABLED_EGU NRF_802154_PPI_RADIO_DISABLED_TO_EGU ///< PPI that connects RADIO DISABLED event with EGU task -#define PPI_EGU_RAMP_UP NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP ///< PPI that connects EGU event with RADIO TXEN or RXEN task -#define PPI_EGU_TIMER_START NRF_802154_PPI_EGU_TO_TIMER_START ///< PPI that connects EGU event with TIMER START task -#define PPI_CRCERROR_CLEAR NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR ///< PPI that connects RADIO CRCERROR event with TIMER CLEAR task -#define PPI_CCAIDLE_FEM NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE ///< PPI that connects RADIO CCAIDLE event with GPIOTE tasks used by FEM -#define PPI_TIMER_TX_ACK NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN ///< PPI that connects TIMER COMPARE event with RADIO TXEN task -#define PPI_CRCOK_DIS_PPI NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE ///< PPI that connects RADIO CRCOK event with task that disables PPI group - -#if NRF_802154_DISABLE_BCC_MATCHING -#define PPI_ADDRESS_COUNTER_COUNT NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT ///< PPI that connects RADIO ADDRESS event with TIMER COUNT task -#define PPI_CRCERROR_COUNTER_CLEAR NRF_802154_PPI_RADIO_CRCERROR_COUNTER_CLEAR ///< PPI that connects RADIO CRCERROR event with TIMER CLEAR task -#endif // NRF_802154_DISABLE_BCC_MATCHING - -#if NRF_802154_DISABLE_BCC_MATCHING -#define SHORT_ADDRESS_BCSTART 0UL -#else // NRF_802154_DISABLE_BCC_MATCHING -#define SHORT_ADDRESS_BCSTART NRF_RADIO_SHORT_ADDRESS_BCSTART_MASK -#endif // NRF_802154_DISABLE_BCC_MATCHING - -/// Value set to SHORTS register when no shorts should be enabled. -#define SHORTS_IDLE 0 - -/// Value set to SHORTS register for RX operation. -#define SHORTS_RX (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ - NRF_RADIO_SHORT_END_DISABLE_MASK | \ - SHORT_ADDRESS_BCSTART) - -#define SHORTS_RX_FREE_BUFFER (NRF_RADIO_SHORT_RXREADY_START_MASK) - -#define SHORTS_TX_ACK (NRF_RADIO_SHORT_TXREADY_START_MASK | \ - NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) - -#define SHORTS_CCA_TX (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ - NRF_RADIO_SHORT_CCABUSY_DISABLE_MASK | \ - NRF_RADIO_SHORT_CCAIDLE_TXEN_MASK | \ - NRF_RADIO_SHORT_TXREADY_START_MASK | \ - NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) - -#define SHORTS_TX (NRF_RADIO_SHORT_TXREADY_START_MASK | \ - NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) - -#define SHORTS_RX_ACK (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ - NRF_RADIO_SHORT_END_DISABLE_MASK) - -#define SHORTS_ED (NRF_RADIO_SHORT_READY_EDSTART_MASK) - -#define SHORTS_CCA (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ - NRF_RADIO_SHORT_CCABUSY_DISABLE_MASK) +#include "nrf_802154_sl_ant_div.h" /// Delay before first check of received frame: 24 bits is PHY header and MAC Frame Control field. -#define BCC_INIT (3 * 8) +#define BCC_INIT (3 * 8) /// Duration of single iteration of Energy Detection procedure -#define ED_ITER_DURATION 128U +#define ED_ITER_DURATION 128U /// Overhead of hardware preparation for ED procedure (aTurnaroundTime) [number of iterations] -#define ED_ITERS_OVERHEAD 2U +#define ED_ITERS_OVERHEAD 2U -#define CRC_LENGTH 2 ///< Length of CRC in 802.15.4 frames [bytes] -#define CRC_POLYNOMIAL 0x011021 ///< Polynomial used for CRC calculation in 802.15.4 frames +#define ACK_IFS TURNAROUND_TIME ///< Ack Inter Frame Spacing [us] - delay between last symbol of received frame and first symbol of transmitted Ack -#define MHMU_MASK 0xff000700 ///< Mask of known bytes in ACK packet -#define MHMU_PATTERN 0x00000200 ///< Values of known bytes in ACK packet -#define MHMU_PATTERN_DSN_OFFSET 24 ///< Offset of DSN in MHMU_PATTER [bits] +#define MAX_CRIT_SECT_TIME 60 ///< Maximal time that the driver spends in single critical section. -#define ACK_IFS TURNAROUND_TIME ///< Ack Inter Frame Spacing [us] - delay between last symbol of received frame and first symbol of transmitted Ack -#define TXRU_TIME 40 ///< Transmitter ramp up time [us] -#define EVENT_LAT 23 ///< END event latency [us] - -#define MAX_CRIT_SECT_TIME 60 ///< Maximal time that the driver spends in single critical section. - -#define LQI_VALUE_FACTOR 4 ///< Factor needed to calculate LQI value based on data from RADIO peripheral -#define LQI_MAX 0xff ///< Maximal LQI value +#define LQI_VALUE_FACTOR 4 ///< Factor needed to calculate LQI value based on data from RADIO peripheral +#define LQI_MAX 0xff ///< Maximal LQI value /** Get LQI of given received packet. If CRC is calculated by hardware LQI is included instead of CRC * in the frame. Length is stored in byte with index 0; CRC is 2 last bytes. */ -#define RX_FRAME_LQI(data) ((data)[(data)[0] - 1]) +#define RX_FRAME_LQI(data) ((data)[(data)[0] - 1]) + +/** Timeout value when waiting for ntf_802154_trx_receive_frame_started after ntf_802154_trx_receive_frame_prestarted. + * Timeout value in microseconds. The time equals to whole synchronization header (SHR) duration of 802.15.4 frame. + */ +#define PRESTARTED_TIMER_TIMEOUT_US (160U) #if NRF_802154_RX_BUFFERS > 1 /// Pointer to currently used receive buffer. @@ -166,9 +114,6 @@ static rx_buffer_t * const mp_current_rx_buffer = &nrf_802154_rx_buffers[0]; #endif -/** Prototype for the Radio IRQ handling routine. */ -static void irq_handler(void); - static const uint8_t * mp_ack; ///< Pointer to Ack frame buffer. static const uint8_t * mp_tx_data; ///< Pointer to the data to transmit. static uint32_t m_ed_time_left; ///< Remaining time of the current energy detection procedure [us]. @@ -176,70 +121,54 @@ static uint8_t m_ed_result; ///< Result of the current energy detecti static volatile radio_state_t m_state; ///< State of the radio driver. -/// Common parameters for the FAL handling. -static const nrf_802154_fal_event_t m_deactivate_on_disable = +typedef struct { - .type = NRF_802154_FAL_EVENT_TYPE_GENERIC, - .override_ppi = false, - .event.generic.register_address = - ((uint32_t)NRF_RADIO_BASE + (uint32_t)NRF_RADIO_EVENT_DISABLED) -}; + bool frame_filtered : 1; ///< If frame being received passed filtering operation. + bool rx_timeslot_requested : 1; ///< If timeslot for the frame being received is already requested. + bool tx_with_cca : 1; ///< If currently transmitted frame is transmitted with cca. + bool tx_diminished_prio : 1; ///< If priority of the current transmission should be diminished. +} nrf_802154_flags_t; -static const nrf_802154_fal_event_t m_activate_rx_cc0 = -{ - .type = NRF_802154_FAL_EVENT_TYPE_TIMER, - .override_ppi = false, - .event.timer = - { - .p_timer_instance = NRF_802154_TIMER_INSTANCE, - .counter_value = RX_RAMP_UP_TIME, - .compare_channel_mask = ((1 << NRF_TIMER_CC_CHANNEL0) | (1 << NRF_TIMER_CC_CHANNEL2)), - }, -}; +static nrf_802154_flags_t m_flags; ///< Flags used to store the current driver state. -static const nrf_802154_fal_event_t m_activate_tx_cc0 = -{ - .type = NRF_802154_FAL_EVENT_TYPE_TIMER, - .override_ppi = false, - .event.timer = - { - .p_timer_instance = NRF_802154_TIMER_INSTANCE, - .counter_value = TX_RAMP_UP_TIME, - .compare_channel_mask = ((1 << NRF_TIMER_CC_CHANNEL0) | (1 << NRF_TIMER_CC_CHANNEL2)), - }, -}; +static volatile bool m_rsch_timeslot_is_granted; ///< State of the RSCH timeslot. +static volatile rsch_prio_t m_rsch_priority = RSCH_PRIO_IDLE; ///< Last notified RSCH priority. -static const nrf_802154_fal_event_t m_ccaidle = -{ - .type = NRF_802154_FAL_EVENT_TYPE_GENERIC, - .override_ppi = true, - .ppi_ch_id = PPI_CCAIDLE_FEM, - .event.generic.register_address = ((uint32_t)NRF_RADIO_BASE + (uint32_t)NRF_RADIO_EVENT_CCAIDLE) -}; +/** @brief Value of argument @c notifications_mask to @ref nrf_802154_trx_receive_frame */ +static nrf_802154_trx_receive_notifications_t m_trx_receive_frame_notifications_mask; +/** @brief Value of argument @c notifications_mask to @ref nrf_802154_trx_transmit_frame */ +static nrf_802154_trx_transmit_notifications_t m_trx_transmit_frame_notifications_mask; -typedef struct -{ - bool frame_filtered : 1; ///< If frame being received passed filtering operation. - bool rx_timeslot_requested : 1; ///< If timeslot for the frame being received is already requested. +static nrf_802154_timer_t m_rx_prestarted_timer; -#if !NRF_802154_DISABLE_BCC_MATCHING - bool psdu_being_received : 1; ///< If PSDU is currently being received. +/** @brief Value of Coex TX Request mode */ +static nrf_802154_coex_tx_request_mode_t m_coex_tx_request_mode; -#endif // !NRF_802154_DISABLE_BCC_MATCHING -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - bool tx_started : 1; ///< If the requested transmission has started. +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED +#if !NRF_802154_FRAME_TIMESTAMP_ENABLED +#error NRF_802154_FRAME_TIMESTAMP_ENABLED == 0 when NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED != 0 +#endif +#if NRF_802154_DISABLE_BCC_MATCHING +#error NRF_802154_DISABLE_BCC_MATCHING != 0 when NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED != 0 +#endif +#endif // NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED - bool rssi_started : 1; -} nrf_802154_flags_t; -static nrf_802154_flags_t m_flags; ///< Flags used to store the current driver state. +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED +static uint32_t m_listening_start_hp_timestamp; -static volatile bool m_rsch_timeslot_is_granted; ///< State of the RSCH timeslot. +#endif /*************************************************************************************************** * @section Common core operations **************************************************************************************************/ +static rsch_prio_t min_required_rsch_prio(radio_state_t state); + +static void request_preconditions_for_state(radio_state_t state) +{ + nrf_802154_rsch_crit_sect_prio_request(min_required_rsch_prio(state)); +} + /** Set driver state. * * @param[in] state Driver state to set. @@ -248,7 +177,10 @@ static void state_set(radio_state_t state) { m_state = state; - nrf_802154_log(EVENT_SET_STATE, (uint32_t)state); + nrf_802154_log_local_event(NRF_802154_LOG_VERBOSITY_LOW, + NRF_802154_LOG_LOCAL_EVENT_ID_CORE__SET_STATE, (uint32_t)state); + + request_preconditions_for_state(state); } /** Clear flags describing frame being received. */ @@ -256,23 +188,12 @@ static void rx_flags_clear(void) { m_flags.frame_filtered = false; m_flags.rx_timeslot_requested = false; -#if !NRF_802154_DISABLE_BCC_MATCHING - m_flags.psdu_being_received = false; -#endif // !NRF_802154_DISABLE_BCC_MATCHING -} - -/** Request the RSSI measurement. */ -static void rssi_measure(void) -{ - m_flags.rssi_started = true; - nrf_radio_event_clear(NRF_RADIO_EVENT_RSSIEND); - nrf_radio_task_trigger(NRF_RADIO_TASK_RSSISTART); } /** Wait for the RSSI measurement. */ static void rssi_measurement_wait(void) { - while (!nrf_radio_event_check(NRF_RADIO_EVENT_RSSIEND)) + while (!nrf_802154_trx_rssi_sample_is_available()) { // Intentionally empty: This function is called from a critical section. // WFE would not be waken up by a RADIO event. @@ -285,7 +206,7 @@ static void rssi_measurement_wait(void) */ static int8_t rssi_last_measurement_get(void) { - uint8_t rssi_sample = nrf_radio_rssi_sample_get(); + uint8_t rssi_sample = nrf_802154_trx_rssi_last_sample_get(); rssi_sample = nrf_802154_rssi_sample_corrected_get(rssi_sample); @@ -313,6 +234,39 @@ static uint8_t lqi_get(const uint8_t * p_data) return (uint8_t)lqi; } +#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) +/** + * @brief Get timestamp made by timer coordinator. + * + * @note This function increments the returned value by 1 us if the timestamp is equal to the + * @ref NRF_802154_NO_TIMESTAMP value to indicate that the timestamp is available. + * + * @returns Timestamp [us] of the last event captured by timer coordinator frame or + * @ref NRF_802154_NO_TIMESTAMP if the timestamp is inaccurate. + */ +static uint32_t timer_coord_timestamp_get(void) +{ + uint32_t timestamp; + bool timestamp_received = nrf_802154_timer_coord_timestamp_get(×tamp); + + if (!timestamp_received) + { + timestamp = NRF_802154_NO_TIMESTAMP; + } + else if (timestamp == NRF_802154_NO_TIMESTAMP) + { + timestamp++; + } + else + { + // Return timestamp without correction + } + + return timestamp; +} + +#endif + static void received_frame_notify(uint8_t * p_data) { nrf_802154_notify_received(p_data, // data @@ -417,51 +371,6 @@ static void cca_notify(bool result) nrf_802154_critical_section_nesting_deny(); } -/** Update CCA configuration in RADIO registers. */ -static void cca_configuration_update(void) -{ - nrf_802154_cca_cfg_t cca_cfg; - - nrf_802154_pib_cca_cfg_get(&cca_cfg); - nrf_radio_cca_configure(cca_cfg.mode, - nrf_802154_rssi_cca_ed_threshold_corrected_get(cca_cfg.ed_threshold), - cca_cfg.corr_threshold, - cca_cfg.corr_limit); -} - -/** Check if PSDU is currently being received. - * - * @returns True if radio is receiving PSDU, false otherwise. - */ -static bool psdu_is_being_received(void) -{ -#if NRF_802154_DISABLE_BCC_MATCHING - nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, - nrf_timer_capture_task_get(NRF_TIMER_CC_CHANNEL0)); - uint32_t counter = nrf_timer_cc_read(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL0); - - assert(counter <= 1); - - return counter > 0; -#else // NRF_802154_DISABLE_BCC_MATCHING - return m_flags.psdu_being_received; -#endif // NRF_802154_DISABLE_BCC_MATCHING -} - -/** Check if requested transmission has already started. - * - * @retval true The transmission has started. - * @retval false The transmission has not started. - */ -static bool transmission_has_started(void) -{ -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - return m_flags.tx_started; -#else // NRF_802154_TX_STARTED_NOTIFY_ENABLED - return nrf_radio_event_check(NRF_RADIO_EVENT_ADDRESS); -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED -} - /** Check if timeslot is currently granted. * * @retval true The timeslot is granted. @@ -472,6 +381,12 @@ static bool timeslot_is_granted(void) return m_rsch_timeslot_is_granted; } +static bool antenna_diversity_is_enabled(void) +{ + return (NRF_802154_SL_ANT_DIV_MODE_DISABLED != + nrf_802154_sl_ant_div_cfg_mode_get(NRF_802154_SL_ANT_DIV_OP_RX)); +} + /*************************************************************************************************** * @section RX buffer management **************************************************************************************************/ @@ -508,21 +423,6 @@ static uint8_t * rx_buffer_get(void) return rx_buffer_is_available() ? mp_current_rx_buffer->data : NULL; } -/*************************************************************************************************** - * @section Radio parameters calculators - **************************************************************************************************/ - -/** Set radio channel - * - * @param[in] channel Channel number to set (11-26). - */ -static void channel_set(uint8_t channel) -{ - assert(channel >= 11 && channel <= 26); - - nrf_radio_frequency_set(2405 + 5 * (channel - 11)); -} - /*************************************************************************************************** * @section ACK transmission management **************************************************************************************************/ @@ -539,127 +439,20 @@ static bool ack_is_requested(const uint8_t * p_frame) return nrf_802154_frame_parser_ar_bit_is_set(p_frame); } -/*************************************************************************************************** - * @section ACK receiving management - **************************************************************************************************/ - -/** Enable hardware ACK matching accelerator. */ -static void ack_matching_enable(void) -{ - nrf_radio_event_clear(NRF_RADIO_EVENT_MHRMATCH); - nrf_radio_mhmu_search_pattern_set(MHMU_PATTERN | - ((uint32_t)mp_tx_data[DSN_OFFSET] << - MHMU_PATTERN_DSN_OFFSET)); -} - -/** Disable hardware ACK matching accelerator. */ -static void ack_matching_disable(void) -{ - nrf_radio_mhmu_search_pattern_set(0); - nrf_radio_event_clear(NRF_RADIO_EVENT_MHRMATCH); -} - -/** Check if hardware ACK matching accelerator matched ACK pattern in received frame. - * - * @retval true ACK matching accelerator matched ACK pattern. - * @retval false ACK matching accelerator did not match ACK pattern. - */ -static bool ack_is_matched(void) -{ - return (nrf_radio_event_check(NRF_RADIO_EVENT_MHRMATCH)) && - (nrf_radio_crc_status_check()); -} - -/*************************************************************************************************** - * @section RADIO peripheral management - **************************************************************************************************/ - -/** Initialize radio peripheral. */ -static void nrf_radio_init(void) -{ - nrf_radio_packet_conf_t packet_conf; - - nrf_radio_mode_set(NRF_RADIO_MODE_IEEE802154_250KBIT); - - memset(&packet_conf, 0, sizeof(packet_conf)); - packet_conf.lflen = 8; - packet_conf.plen = NRF_RADIO_PREAMBLE_LENGTH_32BIT_ZERO; - packet_conf.crcinc = true; - packet_conf.maxlen = MAX_PACKET_SIZE; - nrf_radio_packet_configure(&packet_conf); - - nrf_radio_modecnf0_set(true, 0); - - // Configure CRC - nrf_radio_crc_configure(CRC_LENGTH, NRF_RADIO_CRC_ADDR_IEEE802154, CRC_POLYNOMIAL); - - // Configure CCA - cca_configuration_update(); - - // Configure MAC Header Match Unit - nrf_radio_mhmu_search_pattern_set(0); - nrf_radio_mhmu_pattern_mask_set(MHMU_MASK); - - // Set channel - channel_set(nrf_802154_pib_channel_get()); -} - -/** Reset radio peripheral. */ -static void nrf_radio_reset(void) -{ - nrf_radio_power_set(false); - nrf_radio_power_set(true); - - nrf_802154_log(EVENT_RADIO_RESET, 0); -} - -/** Initialize interrupts for radio peripheral. */ -static void irq_init(void) -{ -#if !NRF_802154_IRQ_PRIORITY_ALLOWED(NRF_802154_IRQ_PRIORITY) -#error NRF_802154_IRQ_PRIORITY value out of the allowed range. -#endif - nrf_802154_irq_init(RADIO_IRQn, NRF_802154_IRQ_PRIORITY, irq_handler); -} - -/** Deinitialize interrupts for radio peripheral. */ -static void irq_deinit(void) -{ - nrf_802154_irq_disable(RADIO_IRQn); - nrf_802154_irq_clear_pending(RADIO_IRQn); -} - -/*************************************************************************************************** - * @section TIMER peripheral management - **************************************************************************************************/ - -/** Initialize TIMER peripheral used by the driver. */ -static void nrf_timer_init(void) -{ - nrf_timer_mode_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_MODE_TIMER); - nrf_timer_bit_width_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_BIT_WIDTH_32); - nrf_timer_frequency_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_FREQ_1MHz); - -#if NRF_802154_DISABLE_BCC_MATCHING - // Setup timer for detecting PSDU reception. - nrf_timer_mode_set(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_MODE_COUNTER); - nrf_timer_bit_width_set(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_BIT_WIDTH_8); -#endif -} - /*************************************************************************************************** * @section Energy detection management **************************************************************************************************/ /** Get ED result value. * - * @returns ED result based on data collected during Energy Detection procedure. + * @param[in] ed_sample Energy Detection sample gathered from TRX module + * @returns ED result based on data collected during Energy Detection procedure. */ -static uint8_t ed_result_get(void) +static uint8_t ed_result_get(uint8_t ed_sample) { - uint32_t result = m_ed_result; + uint32_t result; - result = nrf_802154_rssi_ed_corrected_get(result); + result = nrf_802154_rssi_ed_corrected_get(ed_sample); result *= ED_RESULT_FACTOR; if (result > ED_RESULT_MAX) @@ -675,306 +468,120 @@ static uint8_t ed_result_get(void) * Energy detection procedure is performed in iterations to make sure it is performed for requested * time regardless radio arbitration. * - * @param[in] Remaining time of energy detection procedure [us]. + * @param[inout] p_requested_ed_time_us Remaining time of energy detection procedure [us]. Value will be updated + * with time remaining for the next attempt of energy detection. + * @param[out] p_next_trx_ed_count Number of trx energy detection iterations to perform. * * @retval true Next iteration of energy detection procedure will be performed now. * @retval false Next iteration of energy detection procedure will not be performed now due to * ending timeslot. */ -static bool ed_iter_setup(uint32_t time_us) +static bool ed_iter_setup(uint32_t * p_requested_ed_time_us, uint32_t * p_next_trx_ed_count) { - uint32_t us_left_in_timeslot = nrf_802154_rsch_timeslot_us_left_get(); - uint32_t next_ed_iters = us_left_in_timeslot / ED_ITER_DURATION; + uint32_t iters_left_in_timeslot = nrf_802154_rsch_timeslot_us_left_get() / ED_ITER_DURATION; - if (next_ed_iters > ED_ITERS_OVERHEAD) + if (iters_left_in_timeslot > ED_ITERS_OVERHEAD) { - next_ed_iters -= ED_ITERS_OVERHEAD; + /* Note that in single phy iters_left_in_timeslot will always be very big thus we will get here. */ + iters_left_in_timeslot -= ED_ITERS_OVERHEAD; + + uint32_t requested_iters = *p_requested_ed_time_us / ED_ITER_DURATION; - if ((time_us / ED_ITER_DURATION) < next_ed_iters) + if (requested_iters < iters_left_in_timeslot) { - m_ed_time_left = 0; - next_ed_iters = time_us / ED_ITER_DURATION; + /* We will finish all iterations before timeslot end, thus no time is left */ + *p_requested_ed_time_us = 0U; } else { - m_ed_time_left = time_us - (next_ed_iters * ED_ITER_DURATION); - next_ed_iters--; // Time of ED procedure is (next_ed_iters + 1) * 128us + *p_requested_ed_time_us = *p_requested_ed_time_us - + (iters_left_in_timeslot * ED_ITER_DURATION); + requested_iters = iters_left_in_timeslot; } - nrf_radio_ed_loop_count_set(next_ed_iters); + *p_next_trx_ed_count = requested_iters; return true; } - else - { - // Silently wait for a new timeslot - m_ed_time_left = time_us; - - return false; - } + return false; } /*************************************************************************************************** * @section FSM transition request sub-procedures **************************************************************************************************/ -/** Wait time needed to propagate event through PPI to EGU. - * - * During detection if trigger of DISABLED event caused start of hardware procedure, detecting - * function needs to wait until event is propagated from RADIO through PPI to EGU. This delay is - * required to make sure EGU event is set if hardware was prepared before DISABLED event was - * triggered. - */ -static inline void ppi_and_egu_delay_wait(void) -{ - __ASM("nop"); - __ASM("nop"); - __ASM("nop"); - __ASM("nop"); - __ASM("nop"); - __ASM("nop"); -} - -/** Detect if PPI starting EGU for current operation worked. - * - * @retval true PPI worked. - * @retval false PPI did not work. DISABLED task should be triggered. - */ -static bool ppi_egu_worked(void) -{ - // Detect if PPIs were set before DISABLED event was notified. If not trigger DISABLE - if (nrf_radio_state_get() != NRF_RADIO_STATE_DISABLED) - { - // If RADIO state is not DISABLED, it means that RADIO is still ramping down or already - // started ramping up. - return true; - } - - // Wait for PPIs - ppi_and_egu_delay_wait(); - - if (nrf_egu_event_check(NRF_802154_SWI_EGU_INSTANCE, EGU_EVENT)) - { - // If EGU event is set, procedure is running. - return true; - } - else - { - return false; - } -} - -/** Set PPIs to connect DISABLED->EGU->RAMP_UP - * - * @param[in] ramp_up_task Task triggered to start ramp up procedure. - * @param[in] self_disabling If PPI should disable itself. - */ -static void ppis_for_egu_and_ramp_up_set(nrf_radio_task_t ramp_up_task, bool self_disabling) +static rsch_prio_t min_required_rsch_prio(radio_state_t state) { - if (self_disabling) - { - nrf_ppi_channel_and_fork_endpoint_setup(PPI_EGU_RAMP_UP, - (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), - (uint32_t)nrf_radio_task_address_get(ramp_up_task), - (uint32_t)nrf_ppi_task_address_get( - PPI_CHGRP0_DIS_TASK)); - } - else - { - nrf_ppi_channel_endpoint_setup(PPI_EGU_RAMP_UP, - (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), - (uint32_t)nrf_radio_task_address_get(ramp_up_task)); - } - - nrf_ppi_channel_endpoint_setup(PPI_DISABLED_EGU, - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_DISABLED), - (uint32_t)nrf_egu_task_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_TASK)); - - if (self_disabling) + switch (state) { - nrf_ppi_channel_include_in_group(PPI_EGU_RAMP_UP, PPI_CHGRP0); - } - - nrf_ppi_channel_enable(PPI_EGU_RAMP_UP); - nrf_ppi_channel_enable(PPI_DISABLED_EGU); -} + case RADIO_STATE_SLEEP: + return RSCH_PRIO_IDLE; -/** Configure FEM to set LNA at appropriate time. */ -static void fem_for_lna_set(void) -{ - if (nrf_802154_fal_lna_configuration_set(&m_activate_rx_cc0, NULL) == NRF_SUCCESS) - { - uint32_t event_addr = (uint32_t)nrf_egu_event_address_get(NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT); - uint32_t task_addr = (uint32_t)nrf_timer_task_address_get(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_START); + case RADIO_STATE_FALLING_ASLEEP: + case RADIO_STATE_RX: + return RSCH_PRIO_IDLE_LISTENING; - nrf_timer_shorts_enable(m_activate_rx_cc0.event.timer.p_timer_instance, - NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - nrf_ppi_channel_endpoint_setup(PPI_EGU_TIMER_START, event_addr, task_addr); - nrf_ppi_channel_enable(PPI_EGU_TIMER_START); - } -} + case RADIO_STATE_RX_ACK: + case RADIO_STATE_ED: + case RADIO_STATE_CCA: + return RSCH_PRIO_RX; -/** Reset FEM configuration for LNA. - * - * @param[in] timer_short_mask Mask of shorts that should be disabled on FEM timer. - */ -static void fem_for_lna_reset(void) -{ - nrf_802154_fal_lna_configuration_clear(&m_activate_rx_cc0, NULL); - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - nrf_ppi_channel_disable(PPI_EGU_TIMER_START); -} + case RADIO_STATE_TX: + case RADIO_STATE_TX_ACK: + case RADIO_STATE_CONTINUOUS_CARRIER: + case RADIO_STATE_MODULATED_CARRIER: + return RSCH_PRIO_TX; -/** Configure FEM to set PA at appropriate time. */ -static void fem_for_pa_set(void) -{ - if (nrf_802154_fal_pa_configuration_set(&m_activate_tx_cc0, NULL) == NRF_SUCCESS) - { - uint32_t event_addr = (uint32_t)nrf_egu_event_address_get(NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT); - uint32_t task_addr = (uint32_t)nrf_timer_task_address_get(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_START); + case RADIO_STATE_CCA_TX: + if (m_flags.tx_diminished_prio) + { + return RSCH_PRIO_IDLE_LISTENING; + } + else + { + return RSCH_PRIO_TX; + } - nrf_timer_shorts_enable(m_activate_tx_cc0.event.timer.p_timer_instance, - NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - nrf_ppi_channel_endpoint_setup(PPI_EGU_TIMER_START, event_addr, task_addr); - nrf_ppi_channel_enable(PPI_EGU_TIMER_START); + default: + assert(false); + return RSCH_PRIO_IDLE; } } -/** Reset FEM configuration for PA. */ -static void fem_for_pa_reset(void) +static bool is_state_allowed_for_prio(rsch_prio_t prio, radio_state_t state) { - nrf_802154_fal_pa_configuration_clear(&m_activate_tx_cc0, NULL); - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_ppi_channel_disable(PPI_EGU_TIMER_START); - nrf_802154_fal_deactivate_now(NRF_802154_FAL_PA); + return (min_required_rsch_prio(state) <= prio); } -/** Configure FEM for TX procedure. */ -static void fem_for_tx_set(bool cca) +static bool are_preconditions_met(void) { - bool success; - - if (cca) - { - bool pa_set = false; - bool lna_set = false; - - if (nrf_802154_fal_lna_configuration_set(&m_activate_rx_cc0, &m_ccaidle) == NRF_SUCCESS) - { - lna_set = true; - } - - if (nrf_802154_fal_pa_configuration_set(&m_ccaidle, NULL) == NRF_SUCCESS) - { - pa_set = true; - } - - success = pa_set || lna_set; + rsch_prio_t current_prio; + radio_state_t current_state; - } - else - { - success = (nrf_802154_fal_pa_configuration_set(&m_activate_tx_cc0, NULL) == NRF_SUCCESS); - } + current_prio = m_rsch_priority; + current_state = m_state; - if (success) - { - nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - - uint32_t egu_event_addr = (uint32_t)nrf_egu_event_address_get(NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT); - uint32_t timer_task_addr = (uint32_t)nrf_timer_task_address_get(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_START); - - nrf_ppi_channel_endpoint_setup(PPI_EGU_TIMER_START, egu_event_addr, timer_task_addr); - nrf_ppi_channel_enable(PPI_EGU_TIMER_START); - } + return is_state_allowed_for_prio(current_prio, current_state); } -/** Reset FEM for TX procedure. */ -static void fem_for_tx_reset(bool disable_ppi_egu_timer_start) +static int_fast8_t action_needed(rsch_prio_t old_prio, rsch_prio_t new_prio, radio_state_t state) { - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_SHORT_COMPARE0_STOP_MASK | - NRF_TIMER_SHORT_COMPARE1_STOP_MASK); + bool old_prio_allows = is_state_allowed_for_prio(old_prio, state); + bool new_prio_allows = is_state_allowed_for_prio(new_prio, state); - switch (m_state) - { - case RADIO_STATE_CCA_TX: - nrf_802154_fal_pa_configuration_clear(&m_activate_rx_cc0, &m_ccaidle); - break; - - case RADIO_STATE_TX: - nrf_802154_fal_pa_configuration_clear(&m_activate_tx_cc0, NULL); - break; - - default: - assert(false); - break; - } - - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + int_fast8_t result = 0; - if (disable_ppi_egu_timer_start) + if (old_prio_allows && !new_prio_allows) { - nrf_ppi_channel_disable(PPI_EGU_TIMER_START); + result = -1; } -} - -/** Restart RX procedure after frame was received (and no ACK transmitted). */ -static void rx_restart(bool set_shorts) -{ - // Disable PPIs on DISABLED event to control TIMER. - nrf_ppi_channel_disable(PPI_DISABLED_EGU); - - if (set_shorts) + else if (!old_prio_allows && new_prio_allows) { - nrf_radio_shorts_set(SHORTS_RX); + result = 1; } - // Restart TIMER. - // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - -#if NRF_802154_DISABLE_BCC_MATCHING - // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. - nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); -#endif // NRF_802154_DISABLE_BCC_MATCHING - - // Enable self-disabled PPI or PPI disabled by CRCOK - nrf_ppi_channel_enable(PPI_EGU_RAMP_UP); - - rx_flags_clear(); -#if !NRF_802154_DISABLE_BCC_MATCHING - nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); - nrf_radio_bcc_set(BCC_INIT); -#endif // !NRF_802154_DISABLE_BCC_MATCHING - - // Enable PPIs on DISABLED event and clear event to detect if PPI worked - nrf_egu_event_clear(NRF_802154_SWI_EGU_INSTANCE, EGU_EVENT); - nrf_ppi_channel_enable(PPI_DISABLED_EGU); - - // Prepare the timer coordinator to get a precise timestamp of the CRCOK event. - nrf_802154_timer_coord_timestamp_prepare( - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK)); - - if (!ppi_egu_worked()) - { - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - } + return result; } /** Check if time remaining in the timeslot is long enough to process whole critical section. */ @@ -1013,302 +620,160 @@ static bool critical_section_enter_and_verify_timeslot_length(void) return result; } -/** Terminate Falling Asleep procedure. */ -static void falling_asleep_terminate(void) +static bool can_terminate_current_operation(radio_state_t state, + nrf_802154_term_t term_lvl, + bool receiving_psdu_now) { - if (timeslot_is_granted()) + bool result = false; + + switch (state) { - nrf_radio_int_disable(NRF_RADIO_INT_DISABLED_MASK); - } -} - -/** Terminate Sleep procedure. */ -static void sleep_terminate(void) -{ - nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_MAX); -} - -/** Terminate RX procedure. */ -static void rx_terminate(void) -{ - uint32_t ints_to_disable = 0; - - nrf_ppi_channel_disable(PPI_DISABLED_EGU); - nrf_ppi_channel_disable(PPI_EGU_RAMP_UP); - nrf_ppi_channel_disable(PPI_EGU_TIMER_START); -#if NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_disable(PPI_CRCERROR_CLEAR); - nrf_ppi_channel_disable(PPI_CRCOK_DIS_PPI); - nrf_ppi_channel_disable(PPI_ADDRESS_COUNTER_COUNT); - nrf_ppi_channel_disable(PPI_CRCERROR_COUNTER_CLEAR); - nrf_ppi_channel_endpoint_setup(PPI_CRCERROR_CLEAR, 0, 0); - nrf_ppi_fork_endpoint_setup(PPI_CRCERROR_CLEAR, 0); -#endif // NRF_802154_DISABLE_BCC_MATCHING - - // Disable LNA - nrf_802154_fal_lna_configuration_clear(&m_activate_rx_cc0, NULL); - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_ppi_channel_remove_from_group(PPI_EGU_RAMP_UP, PPI_CHGRP0); - -#if NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_fork_endpoint_setup(PPI_EGU_TIMER_START, 0); -#else // NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0); -#endif // NRF_802154_DISABLE_BCC_MATCHING + case RADIO_STATE_SLEEP: + case RADIO_STATE_FALLING_ASLEEP: + case RADIO_STATE_CONTINUOUS_CARRIER: + case RADIO_STATE_MODULATED_CARRIER: + result = true; + break; - // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + case RADIO_STATE_RX: + result = (term_lvl >= NRF_802154_TERM_802154) || !receiving_psdu_now; + break; -#if NRF_802154_DISABLE_BCC_MATCHING - // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. - nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_timer_shorts_disable(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE1_STOP_MASK); -#endif // NRF_802154_DISABLE_BCC_MATCHING + case RADIO_STATE_TX_ACK: + case RADIO_STATE_CCA_TX: + case RADIO_STATE_TX: + case RADIO_STATE_RX_ACK: + case RADIO_STATE_ED: + case RADIO_STATE_CCA: + result = (term_lvl >= NRF_802154_TERM_802154); + break; - if (timeslot_is_granted()) - { -#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR - ints_to_disable |= NRF_RADIO_INT_CRCERROR_MASK; -#endif // !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR -#if !NRF_802154_DISABLE_BCC_MATCHING - ints_to_disable |= NRF_RADIO_INT_BCMATCH_MASK; -#endif // !NRF_802154_DISABLE_BCC_MATCHING - ints_to_disable |= NRF_RADIO_INT_CRCOK_MASK; - nrf_radio_int_disable(ints_to_disable); - nrf_radio_shorts_set(SHORTS_IDLE); - bool shutdown = nrf_fem_prepare_powerdown(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_CC_CHANNEL0, - PPI_EGU_TIMER_START); - - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - if (shutdown) - { - while (!nrf_timer_event_check(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE0)) - { - // Wait until the event is set. - } - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_ppi_channel_disable(PPI_EGU_TIMER_START); - } + default: + assert(false); } + + return result; } -/** Terminate TX ACK procedure. */ -static void tx_ack_terminate(void) +static void operation_terminated_notify(radio_state_t state, bool receiving_psdu_now) { - uint32_t ints_to_disable = 0; - - nrf_ppi_channel_disable(PPI_DISABLED_EGU); - nrf_ppi_channel_disable(PPI_EGU_RAMP_UP); - nrf_ppi_channel_disable(PPI_EGU_TIMER_START); -#if NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_disable(PPI_CRCERROR_CLEAR); - nrf_ppi_channel_disable(PPI_CRCOK_DIS_PPI); - nrf_ppi_channel_endpoint_setup(PPI_CRCERROR_CLEAR, 0, 0); - nrf_ppi_fork_endpoint_setup(PPI_CRCERROR_CLEAR, 0); -#endif // NRF_802154_DISABLE_BCC_MATCHING - - // Disable PA - nrf_802154_fal_pa_configuration_clear(&m_activate_tx_cc0, NULL); - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - - nrf_ppi_channel_remove_from_group(PPI_EGU_RAMP_UP, PPI_CHGRP0); -#if !NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0); -#endif // !NRF_802154_DISABLE_BCC_MATCHING - - // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - -#if NRF_802154_DISABLE_BCC_MATCHING - // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. - nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_timer_shorts_disable(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE1_STOP_MASK); -#endif // NRF_802154_DISABLE_BCC_MATCHING - - if (timeslot_is_granted()) + switch (state) { - ints_to_disable = NRF_RADIO_INT_PHYEND_MASK; - -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - ints_to_disable |= NRF_RADIO_INT_ADDRESS_MASK; -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED - - nrf_radio_int_disable(ints_to_disable); - nrf_radio_shorts_set(SHORTS_IDLE); - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - } -} + case RADIO_STATE_SLEEP: + case RADIO_STATE_FALLING_ASLEEP: + case RADIO_STATE_CONTINUOUS_CARRIER: + case RADIO_STATE_MODULATED_CARRIER: + break; -/** Terminate TX procedure. */ -static void tx_terminate(void) -{ - uint32_t ints_to_disable; + case RADIO_STATE_RX: + if (receiving_psdu_now) + { + nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_ABORTED); + } - nrf_ppi_channel_disable(PPI_DISABLED_EGU); - nrf_ppi_channel_disable(PPI_EGU_RAMP_UP); + break; - fem_for_tx_reset(true); + case RADIO_STATE_TX_ACK: + mp_current_rx_buffer->free = false; + received_frame_notify(mp_current_rx_buffer->data); + break; - nrf_ppi_channel_remove_from_group(PPI_EGU_RAMP_UP, PPI_CHGRP0); - nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0); + case RADIO_STATE_CCA_TX: + case RADIO_STATE_TX: + transmit_failed_notify(NRF_802154_TX_ERROR_ABORTED); + break; - if (timeslot_is_granted()) - { - ints_to_disable = NRF_RADIO_INT_PHYEND_MASK | NRF_RADIO_INT_CCABUSY_MASK; + case RADIO_STATE_RX_ACK: + transmit_failed_notify(NRF_802154_TX_ERROR_ABORTED); + break; -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - ints_to_disable |= NRF_RADIO_INT_ADDRESS_MASK; -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED + case RADIO_STATE_ED: + nrf_802154_notify_energy_detection_failed(NRF_802154_ED_ERROR_ABORTED); + break; - nrf_radio_int_disable(ints_to_disable); - nrf_radio_shorts_set(SHORTS_IDLE); - bool shutdown = nrf_fem_prepare_powerdown(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_CC_CHANNEL0, - PPI_EGU_TIMER_START); + case RADIO_STATE_CCA: + nrf_802154_notify_cca_failed(NRF_802154_CCA_ERROR_ABORTED); + break; - nrf_radio_task_trigger(NRF_RADIO_TASK_CCASTOP); - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - if (shutdown) - { - while (!nrf_timer_event_check(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE0)) - { - // Wait until the event is set. - } - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_ppi_channel_disable(PPI_EGU_TIMER_START); - } + default: + assert(false); } } -/** Terminate RX ACK procedure. */ -static void rx_ack_terminate(void) +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) +static void operation_terminated_update_total_times(trx_state_t trx_state, uint32_t timestamp) { - uint32_t ints_to_disable; - - nrf_ppi_channel_disable(PPI_DISABLED_EGU); - nrf_ppi_channel_disable(PPI_EGU_RAMP_UP); - - fem_for_lna_reset(); + uint32_t t; - nrf_ppi_channel_remove_from_group(PPI_EGU_RAMP_UP, PPI_CHGRP0); - nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0); - - if (timeslot_is_granted()) + switch (trx_state) { - ints_to_disable = NRF_RADIO_INT_END_MASK; - ints_to_disable |= NRF_RADIO_INT_ADDRESS_MASK; - - nrf_radio_int_disable(ints_to_disable); - nrf_radio_shorts_set(SHORTS_IDLE); - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); + case TRX_STATE_RXFRAME: + case TRX_STATE_RXACK: + t = timestamp - m_listening_start_hp_timestamp; + nrf_802154_stat_totals_increment(total_listening_time, t); + break; - ack_matching_disable(); + default: + break; } } -/** Terminate ED procedure. */ -static void ed_terminate(void) +static bool operation_terminated_update_total_times_is_required(trx_state_t trx_state) { - nrf_ppi_channel_disable(PPI_DISABLED_EGU); - nrf_ppi_channel_disable(PPI_EGU_RAMP_UP); - - fem_for_lna_reset(); - - nrf_ppi_channel_remove_from_group(PPI_EGU_RAMP_UP, PPI_CHGRP0); - nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0); - - if (timeslot_is_granted()) + switch (trx_state) { - bool shutdown = nrf_fem_prepare_powerdown(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_CC_CHANNEL0, - PPI_EGU_TIMER_START); + case TRX_STATE_RXFRAME: + case TRX_STATE_RXACK: + /* These cases must be in-sync with implementation of + * operation_terminated_update_total_times + */ + return true; - nrf_radio_int_disable(NRF_RADIO_INT_EDEND_MASK); - nrf_radio_shorts_set(SHORTS_IDLE); - nrf_radio_task_trigger(NRF_RADIO_TASK_EDSTOP); - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - - if (shutdown) - { - while (!nrf_timer_event_check(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE0)) - { - // Wait until the event is set. - } - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_ppi_channel_disable(PPI_EGU_TIMER_START); - } + default: + return false; } } -/** Terminate CCA procedure. */ -static void cca_terminate(void) +#endif + +static void trx_abort(void) { - nrf_ppi_channel_disable(PPI_DISABLED_EGU); - nrf_ppi_channel_disable(PPI_EGU_RAMP_UP); +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + trx_state_t trx_state = nrf_802154_trx_state_get(); + bool update_required = operation_terminated_update_total_times_is_required(trx_state); - fem_for_lna_reset(); +#endif - nrf_ppi_channel_remove_from_group(PPI_EGU_RAMP_UP, PPI_CHGRP0); - nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0); + nrf_802154_trx_abort(); - if (timeslot_is_granted()) +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + if (update_required) { - bool shutdown = nrf_fem_prepare_powerdown(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_CC_CHANNEL0, - PPI_EGU_TIMER_START); + uint32_t timestamp = nrf_802154_hp_timer_current_time_get(); - nrf_radio_int_disable(NRF_RADIO_INT_CCABUSY_MASK | NRF_RADIO_INT_CCAIDLE_MASK); - nrf_radio_shorts_set(SHORTS_IDLE); - nrf_radio_task_trigger(NRF_RADIO_TASK_CCASTOP); - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - - if (shutdown) - { - while (!nrf_timer_event_check(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE0)) - { - // Wait until the event is set. - } - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_ppi_channel_disable(PPI_EGU_TIMER_START); - } + operation_terminated_update_total_times(trx_state, timestamp); } +#endif } -/** Terminate Continuous Carrier procedure. */ -static void continuous_carrier_terminate(void) +static void trx_disable(void) { - nrf_ppi_channel_disable(PPI_DISABLED_EGU); - nrf_ppi_channel_disable(PPI_EGU_RAMP_UP); +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + trx_state_t trx_state = nrf_802154_trx_state_get(); + bool update_required = operation_terminated_update_total_times_is_required(trx_state); - fem_for_pa_reset(); +#endif - if (timeslot_is_granted()) + nrf_802154_trx_disable(); + +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + if (update_required) { - bool shutdown = nrf_fem_prepare_powerdown(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_CC_CHANNEL0, - PPI_EGU_TIMER_START); + uint32_t timestamp = nrf_802154_hp_timer_current_time_get(); - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - if (shutdown) - { - while (!nrf_timer_event_check(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE0)) - { - // Wait until the event is set. - } - nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_ppi_channel_disable(PPI_EGU_TIMER_START); - } + operation_terminated_update_total_times(trx_state, timestamp); } +#endif } /** Terminate ongoing operation. @@ -1333,134 +798,100 @@ static bool current_operation_terminate(nrf_802154_term_t term_lvl, if (result) { - switch (m_state) - { - case RADIO_STATE_SLEEP: - if (req_orig != REQ_ORIG_RSCH) - { - // Terminate sleep state unless it is requested by Radio Scheduler - // during timeslot end. - sleep_terminate(); - } - - break; - - case RADIO_STATE_FALLING_ASLEEP: - falling_asleep_terminate(); - break; - - case RADIO_STATE_RX: - if (psdu_is_being_received()) - { - if (term_lvl >= NRF_802154_TERM_802154) - { - rx_terminate(); - - if (notify) - { - nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_ABORTED); - } - } - else - { - result = false; - } - } - else - { - rx_terminate(); - } + bool receiving_psdu_now = false; - break; + if (m_state == RADIO_STATE_RX) + { + receiving_psdu_now = nrf_802154_trx_psdu_is_being_received(); + } - case RADIO_STATE_TX_ACK: - if (term_lvl >= NRF_802154_TERM_802154) - { - tx_ack_terminate(); + result = can_terminate_current_operation(m_state, term_lvl, receiving_psdu_now); - if (notify) - { - mp_current_rx_buffer->free = false; - received_frame_notify(mp_current_rx_buffer->data); - } - } - else - { - result = false; - } + if (result) + { + trx_abort(); - break; + if (m_state == RADIO_STATE_RX) + { + /* When in rx mode, nrf_802154_trx_receive_frame_prestarted handler might + * have already been called. We need to stop counting timeout. */ + nrf_802154_timer_sched_remove(&m_rx_prestarted_timer, NULL); + + /* Notify antenna diversity module that RX has been aborted. */ + nrf_802154_sl_ant_div_rx_aborted_notify(); + + /* We might have boosted preconditions (to support coex) above level + * normally requested for current state by request_preconditions_for_state(m_state). + * When current operation is terminated we request preconditions back + * thus ceasing to request to coex. */ + request_preconditions_for_state(m_state); + } - case RADIO_STATE_CCA_TX: - case RADIO_STATE_TX: - if (term_lvl >= NRF_802154_TERM_802154) - { - tx_terminate(); + if (m_state == RADIO_STATE_ED) + { + nrf_802154_sl_ant_div_energy_detection_aborted_notify(); + } - if (notify) - { - transmit_failed_notify(NRF_802154_TX_ERROR_ABORTED); - } - } - else - { - result = false; - } + if (notify) + { + operation_terminated_notify(m_state, receiving_psdu_now); + } + } - break; + } - case RADIO_STATE_RX_ACK: - if (term_lvl >= NRF_802154_TERM_802154) - { - rx_ack_terminate(); + return result; +} - if (notify) - { - transmit_failed_notify(NRF_802154_TX_ERROR_ABORTED); - } - } - else - { - result = false; - } +/** Enter Sleep state. */ +static void sleep_init(void) +{ + nrf_802154_timer_coord_stop(); +} - break; +/** Initialize Falling Asleep operation. */ +static void falling_asleep_init(void) +{ + if (nrf_802154_trx_go_idle()) + { + // There will be nrf_802154_trx_in_idle call, where we will continue processing + } + else + { + sleep_init(); + state_set(RADIO_STATE_SLEEP); + } +} - case RADIO_STATE_ED: - if (term_lvl >= NRF_802154_TERM_802154) - { - ed_terminate(); +/**@brief Makes value to be passed to @ref nrf_802154_trx_receive_frame as @c notifications_mask parameter */ +static nrf_802154_trx_receive_notifications_t make_trx_frame_receive_notification_mask(void) +{ + nrf_802154_trx_receive_notifications_t result = TRX_RECEIVE_NOTIFICATION_NONE; - if (notify) - { - nrf_802154_notify_energy_detection_failed(NRF_802154_ED_ERROR_ABORTED); - } - } - else - { - result = false; - } +#if (NRF_802154_STATS_COUNT_ENERGY_DETECTED_EVENTS) + result |= TRX_RECEIVE_NOTIFICATION_PRESTARTED; +#endif +#if (NRF_802154_STATS_COUNT_RECEIVED_PREAMBLES) + result |= TRX_RECEIVE_NOTIFICATION_STARTED; +#endif + if (nrf_802154_wifi_coex_is_enabled()) + { + switch (nrf_802154_pib_coex_rx_request_mode_get()) + { + case NRF_802154_COEX_RX_REQUEST_MODE_DESTINED: + /* Coex requesting handled through nrf_802154_trx_receive_frame_bcmatched handler. + * No additional notifications required. */ break; - case RADIO_STATE_CCA: - if (term_lvl >= NRF_802154_TERM_802154) - { - cca_terminate(); - - if (notify) - { - nrf_802154_notify_cca_failed(NRF_802154_CCA_ERROR_ABORTED); - } - } - else - { - result = false; - } + case NRF_802154_COEX_RX_REQUEST_MODE_ENERGY_DETECTION: + result |= TRX_RECEIVE_NOTIFICATION_PRESTARTED | TRX_RECEIVE_NOTIFICATION_STARTED; + // Note: TRX_RECEIVE_NOTIFICATION_STARTED is required for stopping counting timeout for + // activity triggered by nrf_802154_trx_receive_frame_prestarted. break; - case RADIO_STATE_CONTINUOUS_CARRIER: - continuous_carrier_terminate(); + case NRF_802154_COEX_RX_REQUEST_MODE_PREAMBLE: + result |= TRX_RECEIVE_NOTIFICATION_STARTED; break; default: @@ -1471,436 +902,236 @@ static bool current_operation_terminate(nrf_802154_term_t term_lvl, return result; } -/** Enter Sleep state. */ -static void sleep_init(void) +/**@brief Makes value to be passed to @ref nrf_802154_trx_transmit_frame as @c notifications_mask parameter + * + * @param[in] cca Pass true, if cca operation it to be performed before transmit. + * Pass false otherwise. + */ +static nrf_802154_trx_transmit_notifications_t make_trx_frame_transmit_notification_mask(bool cca) { - nrf_802154_timer_coord_stop(); - nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_IDLE); -} + nrf_802154_trx_transmit_notifications_t result = TRX_TRANSMIT_NOTIFICATION_NONE; -/** Initialize Falling Asleep operation. */ -static void falling_asleep_init(void) -{ - if (!timeslot_is_granted()) +#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) + if (cca) { - state_set(RADIO_STATE_SLEEP); - sleep_init(); - return; + result |= TRX_TRANSMIT_NOTIFICATION_CCAIDLE; } +#endif - nrf_radio_event_clear(NRF_RADIO_EVENT_DISABLED); - nrf_radio_int_enable(NRF_RADIO_INT_DISABLED_MASK); - - if (nrf_radio_state_get() == NRF_RADIO_STATE_DISABLED) + if (nrf_802154_wifi_coex_is_enabled()) { - // Radio is already disabled. Enter sleep state directly. - falling_asleep_terminate(); - state_set(RADIO_STATE_SLEEP); - sleep_init(); + switch (nrf_802154_pib_coex_tx_request_mode_get()) + { + case NRF_802154_COEX_TX_REQUEST_MODE_FRAME_READY: + case NRF_802154_COEX_TX_REQUEST_MODE_CCA_START: + /* No additional notifications required. */ + break; + + case NRF_802154_COEX_TX_REQUEST_MODE_CCA_DONE: + result |= TRX_TRANSMIT_NOTIFICATION_CCAIDLE; + break; + + default: + assert(false); + } } + + return result; } /** Initialize RX operation. */ -static void rx_init(bool disabled_was_triggered) +static void rx_init(void) { - bool free_buffer; - int32_t ints_to_enable = 0; + bool free_buffer; if (!timeslot_is_granted()) { return; } + if (!are_preconditions_met()) + { + return; + } + // Clear filtering flag rx_flags_clear(); - // Clear the RSSI measurement flag. - m_flags.rssi_started = false; - - nrf_radio_txpower_set(nrf_802154_pib_tx_power_get()); // Find available RX buffer free_buffer = rx_buffer_is_available(); - if (free_buffer) - { - nrf_radio_packetptr_set(rx_buffer_get()); - } - - // Set shorts - nrf_radio_shorts_set(free_buffer ? (SHORTS_RX | SHORTS_RX_FREE_BUFFER) : (SHORTS_RX)); + nrf_802154_trx_receive_buffer_set(rx_buffer_get()); - // Set BCC -#if !NRF_802154_DISABLE_BCC_MATCHING - nrf_radio_bcc_set(BCC_INIT); -#endif // !NRF_802154_DISABLE_BCC_MATCHING - - // Enable IRQs -#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR - nrf_radio_event_clear(NRF_RADIO_EVENT_CRCERROR); - ints_to_enable |= NRF_RADIO_INT_CRCERROR_MASK; -#endif // !NRF_802154_DISABLE_BCC_MATCHING ||NRF_802154_NOTIFY_CRCERROR -#if !NRF_802154_DISABLE_BCC_MATCHING - nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); - ints_to_enable |= NRF_RADIO_INT_BCMATCH_MASK; -#endif // !NRF_802154_DISABLE_BCC_MATCHING - nrf_radio_event_clear(NRF_RADIO_EVENT_CRCOK); - ints_to_enable |= NRF_RADIO_INT_CRCOK_MASK; - nrf_radio_int_enable(ints_to_enable); + nrf_802154_trx_receive_frame(BCC_INIT / 8U, m_trx_receive_frame_notifications_mask); - // Set FEM - nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_SHORT_COMPARE0_STOP_MASK); +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED + m_listening_start_hp_timestamp = nrf_802154_hp_timer_current_time_get(); +#endif - uint32_t delta_time; +#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + // Configure the timer coordinator to get a timestamp of the END event which + // fires several cycles after CRCOK or CRCERROR events. + nrf_802154_timer_coord_timestamp_prepare( + nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_END)); +#else + // Configure the timer coordinator to get a timestamp of the CRCOK event. + nrf_802154_timer_coord_timestamp_prepare(nrf_radio_event_address_get(NRF_RADIO, + NRF_RADIO_EVENT_CRCOK)); +#endif +#endif - if (nrf_802154_fal_lna_configuration_set(&m_activate_rx_cc0, NULL) == NRF_SUCCESS) - { - delta_time = nrf_timer_cc_read(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_CC_CHANNEL0); - } - else - { - delta_time = 1; - nrf_timer_cc_write(NRF_802154_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL0, delta_time); - } - - nrf_timer_cc_write(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_CC_CHANNEL1, - delta_time + ACK_IFS - TXRU_TIME - EVENT_LAT); - -#if NRF_802154_DISABLE_BCC_MATCHING - nrf_timer_shorts_enable(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE1_STOP_MASK); - nrf_timer_cc_write(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL1, 1); -#endif // NRF_802154_DISABLE_BCC_MATCHING - - // Clr event EGU - nrf_egu_event_clear(NRF_802154_SWI_EGU_INSTANCE, EGU_EVENT); - - // Set PPIs -#if NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_endpoint_setup(PPI_EGU_RAMP_UP, - (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), - (uint32_t)nrf_radio_task_address_get(NRF_RADIO_TASK_RXEN)); - nrf_ppi_channel_and_fork_endpoint_setup(PPI_EGU_TIMER_START, - (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), - (uint32_t)nrf_timer_task_address_get( - NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_START), - (uint32_t)nrf_timer_task_address_get( - NRF_802154_COUNTER_TIMER_INSTANCE, - NRF_TIMER_TASK_START)); - // Anomaly 78: use SHUTDOWN instead of CLEAR. - nrf_ppi_channel_endpoint_setup(PPI_CRCERROR_CLEAR, - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCERROR), - (uint32_t)nrf_timer_task_address_get( - NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_SHUTDOWN)); - nrf_ppi_channel_endpoint_setup(PPI_CRCOK_DIS_PPI, - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK), - (uint32_t)nrf_ppi_task_address_get(PPI_CHGRP0_DIS_TASK)); -#else // NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_and_fork_endpoint_setup(PPI_EGU_RAMP_UP, - (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), - (uint32_t)nrf_radio_task_address_get( - NRF_RADIO_TASK_RXEN), - (uint32_t)nrf_ppi_task_address_get( - PPI_CHGRP0_DIS_TASK)); - nrf_ppi_channel_endpoint_setup(PPI_EGU_TIMER_START, - (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), - (uint32_t)nrf_timer_task_address_get( - NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_START)); -#endif // NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_include_in_group(PPI_EGU_RAMP_UP, PPI_CHGRP0); - - nrf_ppi_channel_endpoint_setup(PPI_DISABLED_EGU, - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_DISABLED), - (uint32_t)nrf_egu_task_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_TASK)); -#if NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_endpoint_setup(PPI_ADDRESS_COUNTER_COUNT, - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_ADDRESS), - (uint32_t)nrf_timer_task_address_get( - NRF_802154_COUNTER_TIMER_INSTANCE, - NRF_TIMER_TASK_COUNT)); - // Anomaly 78: use SHUTDOWN instead of CLEAR. - nrf_ppi_channel_endpoint_setup(PPI_CRCERROR_COUNTER_CLEAR, - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCERROR), - (uint32_t)nrf_timer_task_address_get( - NRF_802154_COUNTER_TIMER_INSTANCE, - NRF_TIMER_TASK_SHUTDOWN)); -#endif // NRF_802154_DISABLE_BCC_MATCHING - - nrf_ppi_channel_enable(PPI_EGU_RAMP_UP); - nrf_ppi_channel_enable(PPI_EGU_TIMER_START); -#if NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_enable(PPI_CRCERROR_CLEAR); - nrf_ppi_channel_enable(PPI_CRCOK_DIS_PPI); - nrf_ppi_channel_enable(PPI_ADDRESS_COUNTER_COUNT); - nrf_ppi_channel_enable(PPI_CRCERROR_COUNTER_CLEAR); -#endif // NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_enable(PPI_DISABLED_EGU); - - // Configure the timer coordinator to get a timestamp of the CRCOK event. - nrf_802154_timer_coord_timestamp_prepare( - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK)); - - // Start procedure if necessary - if (!disabled_was_triggered || !ppi_egu_worked()) - { - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - } - - // Find RX buffer if none available - if (!free_buffer) + // Find RX buffer if none available + if (!free_buffer) { rx_buffer_in_use_set(nrf_802154_rx_buffer_free_find()); - if (rx_buffer_is_available()) - { - nrf_radio_packetptr_set(rx_buffer_get()); - nrf_radio_shorts_set(SHORTS_RX | SHORTS_RX_FREE_BUFFER); - - if (nrf_radio_state_get() == NRF_RADIO_STATE_RXIDLE) - { - nrf_radio_task_trigger(NRF_RADIO_TASK_START); - } - } + nrf_802154_trx_receive_buffer_set(rx_buffer_get()); } } /** Initialize TX operation. */ -static bool tx_init(const uint8_t * p_data, bool cca, bool disabled_was_triggered) +static bool tx_init(const uint8_t * p_data, bool cca) { - uint32_t ints_to_enable = 0; - if (!timeslot_is_granted() || !nrf_802154_rsch_timeslot_request( nrf_802154_tx_duration_get(p_data[0], cca, ack_is_requested(p_data)))) { return false; } - nrf_radio_txpower_set(nrf_802154_pib_tx_power_get()); - nrf_radio_packetptr_set(p_data); - - // Set shorts - nrf_radio_shorts_set(cca ? SHORTS_CCA_TX : SHORTS_TX); - - // Enable IRQs - nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); - ints_to_enable |= NRF_RADIO_INT_PHYEND_MASK; + if (!are_preconditions_met()) + { + return false; + } +#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) if (cca) { - nrf_radio_event_clear(NRF_RADIO_EVENT_CCABUSY); - ints_to_enable |= NRF_RADIO_INT_CCABUSY_MASK; + // Configure the timer coordinator to get a time stamp of the READY event. + // Note: This event triggers CCASTART, so the time stamp of READY event + // is the time stamp when CCA started. + nrf_802154_timer_coord_timestamp_prepare(nrf_radio_event_address_get(NRF_RADIO, + NRF_RADIO_EVENT_READY)); } - - nrf_radio_event_clear(NRF_RADIO_EVENT_ADDRESS); -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; - m_flags.tx_started = false; -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED - - nrf_radio_int_enable(ints_to_enable); - - // Set FEM - fem_for_tx_set(cca); - - // Clr event EGU - nrf_egu_event_clear(NRF_802154_SWI_EGU_INSTANCE, EGU_EVENT); - - // Set PPIs - ppis_for_egu_and_ramp_up_set(cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, true); - - if (!disabled_was_triggered || !ppi_egu_worked()) + else { - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); + // Configure the timer coordinator to get a time stamp of the PHYEND event. + nrf_802154_timer_coord_timestamp_prepare(nrf_radio_event_address_get(NRF_RADIO, + NRF_RADIO_EVENT_PHYEND)); } +#endif + + m_flags.tx_with_cca = cca; + nrf_802154_trx_transmit_frame(p_data, + cca, + m_trx_transmit_frame_notifications_mask); return true; } /** Initialize ED operation */ -static void ed_init(bool disabled_was_triggered) +static void ed_init(void) { - if (!timeslot_is_granted() || !ed_iter_setup(m_ed_time_left)) + if (!timeslot_is_granted()) { - // Just wait for next timeslot if there is not enough time in this one. return; } - // Set shorts - nrf_radio_shorts_set(SHORTS_ED); - - // Enable IRQs - nrf_radio_event_clear(NRF_RADIO_EVENT_EDEND); - nrf_radio_int_enable(NRF_RADIO_INT_EDEND_MASK); - - // Set FEM - fem_for_lna_set(); + if (!are_preconditions_met()) + { + return; + } - // Clr event EGU - nrf_egu_event_clear(NRF_802154_SWI_EGU_INSTANCE, EGU_EVENT); + uint32_t trx_ed_count = 0U; - // Set PPIs - ppis_for_egu_and_ramp_up_set(NRF_RADIO_TASK_RXEN, true); + // Notify antenna diversity about energy detection request. Antenna diversity state + // will be updated, and m_ed_time_left reduced accordingly. + nrf_802154_sl_ant_div_energy_detection_requested_notify(&m_ed_time_left); - if (!disabled_was_triggered || !ppi_egu_worked()) + if (!ed_iter_setup(&m_ed_time_left, &trx_ed_count)) { - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); + // Just wait for next timeslot if there is not enough time in this one. + return; } + + nrf_802154_trx_energy_detection(trx_ed_count); } /** Initialize CCA operation. */ -static void cca_init(bool disabled_was_triggered) +static void cca_init(void) { if (!timeslot_is_granted() || !nrf_802154_rsch_timeslot_request(nrf_802154_cca_duration_get())) { return; } - // Set shorts - nrf_radio_shorts_set(SHORTS_CCA); - - // Enable IRQs - nrf_radio_event_clear(NRF_RADIO_EVENT_CCABUSY); - nrf_radio_event_clear(NRF_RADIO_EVENT_CCAIDLE); - nrf_radio_int_enable(NRF_RADIO_INT_CCABUSY_MASK | NRF_RADIO_INT_CCAIDLE_MASK); - - // Set FEM - fem_for_lna_set(); - - // Clr event EGU - nrf_egu_event_clear(NRF_802154_SWI_EGU_INSTANCE, EGU_EVENT); - - // Set PPIs - ppis_for_egu_and_ramp_up_set(NRF_RADIO_TASK_RXEN, true); - - if (!disabled_was_triggered || !ppi_egu_worked()) + if (!are_preconditions_met()) { - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); + return; } + + nrf_802154_trx_standalone_cca(); } /** Initialize Continuous Carrier operation. */ -static void continuous_carrier_init(bool disabled_was_triggered) +static void continuous_carrier_init(void) { if (!timeslot_is_granted()) { return; } - // Set Tx Power - nrf_radio_txpower_set(nrf_802154_pib_tx_power_get()); - - // Set FEM - fem_for_pa_set(); - - // Clr event EGU - nrf_egu_event_clear(NRF_802154_SWI_EGU_INSTANCE, EGU_EVENT); - - // Set PPIs - ppis_for_egu_and_ramp_up_set(NRF_RADIO_TASK_TXEN, false); - - if (!disabled_was_triggered || !ppi_egu_worked()) + if (!are_preconditions_met()) { - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); + return; } -} -/*************************************************************************************************** - * @section Radio Scheduler notification handlers - **************************************************************************************************/ + nrf_802154_trx_continuous_carrier(); +} -static void cont_prec_approved(void) +/** Initialize Modulated Carrier operation. */ +static void modulated_carrier_init(const uint8_t * p_data) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TIMESLOT_STARTED); - - if (remaining_timeslot_time_is_enough_for_crit_sect() && !timeslot_is_granted()) + if (!timeslot_is_granted()) { - nrf_radio_reset(); - nrf_radio_init(); - irq_init(); - - assert(nrf_radio_shorts_get() == SHORTS_IDLE); - - m_rsch_timeslot_is_granted = true; - nrf_802154_timer_coord_start(); - - nrf_802154_fal_pa_configuration_set(NULL, &m_deactivate_on_disable); - nrf_802154_fal_lna_configuration_set(NULL, &m_deactivate_on_disable); - - switch (m_state) - { - case RADIO_STATE_SLEEP: - // Intentionally empty. Appropriate action will be performed on state change. - break; - - case RADIO_STATE_RX: - rx_init(false); - break; - - case RADIO_STATE_CCA_TX: - (void)tx_init(mp_tx_data, true, false); - break; - - case RADIO_STATE_TX: - (void)tx_init(mp_tx_data, false, false); - break; - - case RADIO_STATE_ED: - ed_init(false); - break; - - case RADIO_STATE_CCA: - cca_init(false); - break; - - case RADIO_STATE_CONTINUOUS_CARRIER: - continuous_carrier_init(false); - break; + return; + } - default: - assert(false); - } + if (!are_preconditions_met()) + { + return; } - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TIMESLOT_STARTED); + nrf_802154_trx_modulated_carrier((const void *)p_data); } -static void cont_prec_denied(void) +/*************************************************************************************************** + * @section Radio Scheduler notification handlers + **************************************************************************************************/ +static void on_timeslot_ended(void) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TIMESLOT_ENDED); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); if (timeslot_is_granted()) { m_rsch_timeslot_is_granted = false; - if (nrf_802154_rsch_timeslot_is_requested()) + bool receiving_psdu_now = false; + + if (m_state == RADIO_STATE_RX) { - irq_deinit(); - nrf_radio_reset(); + receiving_psdu_now = nrf_802154_trx_psdu_is_being_received(); } - nrf_802154_fal_pa_configuration_clear(NULL, &m_deactivate_on_disable); - nrf_802154_fal_lna_configuration_clear(NULL, &m_deactivate_on_disable); + trx_disable(); - nrf_802154_fal_deactivate_now(NRF_802154_FAL_ALL); nrf_802154_timer_coord_stop(); - result = current_operation_terminate(NRF_802154_TERM_802154, REQ_ORIG_RSCH, false); + nrf_802154_rsch_continuous_ended(); + + result = nrf_802154_core_hooks_terminate(NRF_802154_TERM_802154, REQ_ORIG_RSCH); assert(result); (void)result; @@ -1908,11 +1139,10 @@ static void cont_prec_denied(void) { case RADIO_STATE_FALLING_ASLEEP: state_set(RADIO_STATE_SLEEP); - sleep_init(); break; case RADIO_STATE_RX: - if (psdu_is_being_received()) + if (receiving_psdu_now) { receive_failed_notify(NRF_802154_RX_ERROR_TIMESLOT_ENDED); } @@ -1935,6 +1165,7 @@ static void cont_prec_denied(void) case RADIO_STATE_ED: case RADIO_STATE_CCA: case RADIO_STATE_CONTINUOUS_CARRIER: + case RADIO_STATE_MODULATED_CARRIER: case RADIO_STATE_SLEEP: // Intentionally empty. break; @@ -1944,146 +1175,612 @@ static void cont_prec_denied(void) } } - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TIMESLOT_ENDED); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void on_preconditions_denied(radio_state_t state) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + bool result; + + result = nrf_802154_core_hooks_terminate(NRF_802154_TERM_802154, REQ_ORIG_CORE); + assert(result); + (void)result; + + bool receiving_psdu_now = false; + + if (state == RADIO_STATE_RX) + { + receiving_psdu_now = nrf_802154_trx_psdu_is_being_received(); + } + + trx_abort(); + + switch (state) + { + case RADIO_STATE_FALLING_ASLEEP: + // There should be on_timeslot_ended event + break; + + case RADIO_STATE_RX: + if (receiving_psdu_now) + { + receive_failed_notify(NRF_802154_RX_ERROR_ABORTED); + } + + break; + + case RADIO_STATE_TX_ACK: + state_set(RADIO_STATE_RX); + break; + + case RADIO_STATE_CCA_TX: + m_flags.tx_diminished_prio = false; + // Fallthrough + + case RADIO_STATE_TX: + case RADIO_STATE_RX_ACK: + state_set(RADIO_STATE_RX); + break; + + case RADIO_STATE_ED: + case RADIO_STATE_CCA: + case RADIO_STATE_CONTINUOUS_CARRIER: + case RADIO_STATE_MODULATED_CARRIER: + case RADIO_STATE_SLEEP: + // Intentionally empty. + break; + + default: + assert(false); + } + + operation_terminated_notify(state, receiving_psdu_now); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void on_preconditions_approved(radio_state_t state) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + trx_abort(); + + switch (state) + { + case RADIO_STATE_SLEEP: + // Intentionally empty. Appropriate action will be performed on state change. + break; + + case RADIO_STATE_RX: + rx_init(); + break; + + case RADIO_STATE_CCA_TX: + (void)tx_init(mp_tx_data, true); + break; + + case RADIO_STATE_TX: + (void)tx_init(mp_tx_data, false); + break; + + case RADIO_STATE_ED: + ed_init(); + break; + + case RADIO_STATE_CCA: + cca_init(); + break; + + case RADIO_STATE_CONTINUOUS_CARRIER: + continuous_carrier_init(); + break; + + case RADIO_STATE_MODULATED_CARRIER: + modulated_carrier_init(mp_tx_data); + break; + + default: + assert(false); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void on_timeslot_started(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + nrf_802154_trx_enable(); + + m_rsch_timeslot_is_granted = true; + + nrf_802154_timer_coord_start(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static bool preconditions_approved_should_be_ignored(rsch_prio_t previously_approved_prio, + rsch_prio_t currently_approved_prio) +{ + // Approved preconditions should only be ignored only all the following conditions are met: + // * all preconditions apart from Coex had already been approved; + // * the call is a result of Coex becoming approved at the highest priority; + // * currently performed operation is transmission with CCA; + // * Coex for transmission is requested after CCA reports idle channel + bool only_coex_was_unapproved = (previously_approved_prio == RSCH_PRIO_RX); + bool all_preconditions_are_approved = (currently_approved_prio == RSCH_PRIO_MAX); + bool current_state_is_cca_tx = (m_state == RADIO_STATE_CCA_TX); + bool coex_tx_request_mode_allows = (m_coex_tx_request_mode == + NRF_802154_COEX_TX_REQUEST_MODE_CCA_DONE); + + return (only_coex_was_unapproved && + all_preconditions_are_approved && + current_state_is_cca_tx && + coex_tx_request_mode_allows); } void nrf_802154_rsch_crit_sect_prio_changed(rsch_prio_t prio) { - if (prio > RSCH_PRIO_IDLE) + rsch_prio_t old_prio = m_rsch_priority; + + m_rsch_priority = prio; + + if ((old_prio == RSCH_PRIO_IDLE) && (prio != RSCH_PRIO_IDLE)) { - cont_prec_approved(); + // We have just got a timeslot. + on_timeslot_started(); } - else + else if ((old_prio != RSCH_PRIO_IDLE) && (prio == RSCH_PRIO_IDLE)) + { + // We are giving back timeslot. + on_timeslot_ended(); + return; + } + else if (prio == RSCH_PRIO_IDLE) { - cont_prec_denied(); + // It might happen that even though IDLE has already been notified, this function is called + // again as a result of preemptions caused by unexpected timeslot change (e.g. the application + // requested transition to sleep while out of timeslot and RAAL notified timeslot start + // in the middle of that sleep request). The following block makes RAAL finish its processing. nrf_802154_rsch_continuous_ended(); } + else + { + // Intentionally empty + } + + int_fast8_t transition = action_needed(old_prio, prio, m_state); + + if (transition == 0) + { + return; + } + else if (transition < 0) + { + on_preconditions_denied(m_state); + + // After denying preconditions, TRX is disabled. However, it is possible that the existing + // preconditions are enough for the new state (entered due to denied preconditions) and TRX + // could be enabled for the new state. If this is the case, on_preconditions_approved() is + // called to fully switch to the new state. + radio_state_t new_state = m_state; + + if (is_state_allowed_for_prio(prio, new_state)) + { + on_preconditions_approved(new_state); + } + } + else + { + if (!preconditions_approved_should_be_ignored(old_prio, prio)) + { + on_preconditions_approved(m_state); + } + } } /*************************************************************************************************** * @section RADIO interrupt handler **************************************************************************************************/ -static void irq_address_state_tx_frame(void) +void nrf_802154_trx_receive_ack_started(void) { - transmit_started_notify(); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - m_flags.tx_started = true; -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED + assert(m_state == RADIO_STATE_RX_ACK); + nrf_802154_core_hooks_rx_ack_started(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void on_rx_prestarted_timeout(void * p_context) +{ + (void)p_context; + + /* If we were in critical section this handler would not be called. + * If we were outside of critical section this handler could be called, + * and nrf_802154_critical_section_enter must succeed. + * Justification: + * - If higher priority interrupt preempts this handler before it takes critical section, that + * interrupt may enter/exit critical section, but when it returns to this handler + * entering critical section will succeed. + * - If we entered critical section here the higher priority interrupt from radio + * will not occur. + * - The only related interrupt that can preempt this handler while it owns critical section + * is from raal timeslot margin, which will fail to enter critical section and schedule + * priority change to be called by nrf_802154_critical_section_exit. + * + * Critical section is entered forcefully here nonetheless, due to a rare issue with + * nrf_802154_critical_section_exit being preempted before the nested critical section counter + * could be decremented. Allowing for critical section nesting here resolves the problem. + * TODO: After the bug is fixed, change to nrf_802154_critical_section_enter and check if + * critical section was successfully entered. + */ + + nrf_802154_critical_section_forcefully_enter(); + + nrf_802154_sl_ant_div_rx_preamble_timeout_notify(); + + /** + * If timer is still running here, it means that timer handling has been preempted by HELPER1 + * radio event after removing the timer from scheduler, but before handling this callback. + * In that case, process the timeout as usual, but notify antenna diversity module that another + * preamble was detected in order to repeat RSSI measurements. + */ + if (nrf_802154_timer_sched_is_running(&m_rx_prestarted_timer)) + { + nrf_802154_sl_ant_div_rx_preamble_detected_notify(); + } + + /* If nrf_802154_trx_receive_frame_prestarted boosted preconditions beyond those normally + * required by current state, they need to be restored now. + */ + if (nrf_802154_pib_coex_rx_request_mode_get() == + NRF_802154_COEX_RX_REQUEST_MODE_ENERGY_DETECTION) + { + request_preconditions_for_state(m_state); + } + nrf_802154_critical_section_exit(); } -static void irq_address_state_tx_ack(void) +void nrf_802154_trx_receive_frame_prestarted(void) { - nrf_802154_tx_ack_started(mp_ack); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + if (!antenna_diversity_is_enabled()) + { + // Only assert if notifications mask would not allow for calling this function. + assert((m_trx_receive_frame_notifications_mask & TRX_RECEIVE_NOTIFICATION_PRESTARTED) != + 0U); + } + else + { + // Antenna diversity uses this function for detecting possible preamble on air. + } + + assert(m_state == RADIO_STATE_RX); + +#if (NRF_802154_STATS_COUNT_ENERGY_DETECTED_EVENTS) + nrf_802154_stat_counter_increment(received_energy_events); +#endif + + nrf_802154_sl_ant_div_rx_preamble_detected_notify(); + + // Antenna diversity module should be notified if framestart doesn't come. + bool rx_timeout_should_be_started = antenna_diversity_is_enabled(); + + if (nrf_802154_pib_coex_rx_request_mode_get() == + NRF_802154_COEX_RX_REQUEST_MODE_ENERGY_DETECTION) + { + // Request boosted preconditions for receive + nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_RX); + // Boosted preconditions should be reverted if the framestart doesn't come. + rx_timeout_should_be_started = true; + } + + /* + * This handler might not be followed by nrf_802154_trx_receive_frame_started. The timer + * below is used for timing out if the framestart doesn't come. + * There are two reasons for that: reverting boosted preconditions and notifying antenna diversity + * module. + */ + if (rx_timeout_should_be_started) + { + + uint32_t now = nrf_802154_timer_sched_time_get(); + + nrf_802154_timer_sched_remove(&m_rx_prestarted_timer, NULL); + + m_rx_prestarted_timer.t0 = now; + m_rx_prestarted_timer.dt = PRESTARTED_TIMER_TIMEOUT_US; + m_rx_prestarted_timer.callback = on_rx_prestarted_timeout; + + nrf_802154_timer_sched_add(&m_rx_prestarted_timer, true); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } -static void irq_address_state_rx_ack(void) +void nrf_802154_trx_receive_frame_started(void) { - nrf_802154_core_hooks_rx_ack_started(); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert(m_state == RADIO_STATE_RX); + assert((m_trx_receive_frame_notifications_mask & TRX_RECEIVE_NOTIFICATION_STARTED) != 0U); + +#if (NRF_802154_STATS_COUNT_RECEIVED_PREAMBLES) + nrf_802154_stat_counter_increment(received_preambles); +#endif + + switch (nrf_802154_pib_coex_rx_request_mode_get()) + { + case NRF_802154_COEX_RX_REQUEST_MODE_ENERGY_DETECTION: + nrf_802154_timer_sched_remove(&m_rx_prestarted_timer, NULL); + /* Fallthrough */ + + case NRF_802154_COEX_RX_REQUEST_MODE_PREAMBLE: + /* Request boosted preconditions */ + nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_RX); + break; + + default: + break; + } + + if (antenna_diversity_is_enabled()) + { + // If antenna diversity is enabled, rx_prestarted_timer would be started even + // in different coex rx request modes than NRF_802154_COEX_RX_REQUEST_MODE_ENERGY_DETECTION + nrf_802154_timer_sched_remove(&m_rx_prestarted_timer, NULL); + nrf_802154_sl_ant_div_rx_frame_started_notify(); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } #if !NRF_802154_DISABLE_BCC_MATCHING -// This event is generated during frame reception to request Radio Scheduler timeslot -// and to filter frame -static void irq_bcmatch_state_rx(void) +uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + uint8_t prev_num_data_bytes; uint8_t num_data_bytes; nrf_802154_rx_error_t filter_result; bool frame_accepted = true; - num_data_bytes = nrf_radio_bcc_get() / 8; + num_data_bytes = bcc; prev_num_data_bytes = num_data_bytes; assert(num_data_bytes >= PHR_SIZE + FCF_SIZE); + assert(m_state == RADIO_STATE_RX); - // If CRCERROR event is set, it means that events are handled out of order due to software - // latency. Just skip this handler in this case - frame will be dropped. - if (nrf_radio_event_check(NRF_RADIO_EVENT_CRCERROR)) + if (!m_flags.frame_filtered) { - return; + filter_result = nrf_802154_filter_frame_part(mp_current_rx_buffer->data, + &num_data_bytes); + + if (filter_result == NRF_802154_RX_ERROR_NONE) + { + if (num_data_bytes != prev_num_data_bytes) + { + bcc = num_data_bytes; + } + else + { + m_flags.frame_filtered = true; + + /* Request boosted preconditions */ + nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_RX); + } + } + else if ((filter_result == NRF_802154_RX_ERROR_INVALID_LENGTH) || + (!nrf_802154_pib_promiscuous_get())) + { + trx_abort(); + rx_init(); + + frame_accepted = false; + + /* Release boosted preconditions */ + request_preconditions_for_state(m_state); + + if ((mp_current_rx_buffer->data[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) != + FRAME_TYPE_ACK) + { + receive_failed_notify(filter_result); + } + } + else + { + // Promiscuous mode, allow incorrect frames. Nothing to do here. + } } - if (!m_flags.frame_filtered) + if ((!m_flags.rx_timeslot_requested) && (frame_accepted)) + { + if (nrf_802154_rsch_timeslot_request(nrf_802154_rx_duration_get( + mp_current_rx_buffer->data[0], + ack_is_requested(mp_current_rx_buffer->data)))) + { + m_flags.rx_timeslot_requested = true; + + receive_started_notify(); + } + else + { + // Disable receiver and wait for a new timeslot. + trx_abort(); + + // We should not leave trx in temporary state, let's receive then. + // We avoid hard reset of radio during TX ACK phase due to timeslot end, + // which could result in spurious RF emission. + rx_init(); + + nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_TIMESLOT_ENDED); + } + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + + return bcc; +} + +#endif + +void nrf_802154_trx_go_idle_finished(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + sleep_init(); + state_set(RADIO_STATE_SLEEP); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void on_bad_ack(void); + +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED +static void update_total_times_on_receive_end(uint32_t listening_start_hp_timestamp, + uint32_t receive_end_hp_timestamp, uint8_t phr) +{ + uint32_t t_listening; + uint32_t t_frame; + + t_frame = nrf_802154_frame_duration_get(phr, true, true); + t_listening = receive_end_hp_timestamp - listening_start_hp_timestamp; + + if (t_frame > t_listening) + { + t_frame = t_listening; + } + + t_listening -= t_frame; + + nrf_802154_stat_totals_increment(total_listening_time, t_listening); + nrf_802154_stat_totals_increment(total_receive_time, t_frame); +} + +#endif + +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED +void nrf_802154_stat_totals_get_notify(void) +{ + // Total times are going to be read, update stat_totals to hold + // correct times until now. + + nrf_802154_mcu_critical_state_t mcu_cs; + + nrf_802154_mcu_critical_enter(mcu_cs); + + trx_state_t trx_state = nrf_802154_trx_state_get(); + + if ((trx_state == TRX_STATE_RXFRAME) || (trx_state == TRX_STATE_RXACK)) { - m_flags.psdu_being_received = true; - filter_result = nrf_802154_filter_frame_part(mp_current_rx_buffer->data, - &num_data_bytes); + uint32_t listening_end_timestamp = nrf_802154_hp_timer_current_time_get(); - if (filter_result == NRF_802154_RX_ERROR_NONE) - { - if (num_data_bytes != prev_num_data_bytes) - { - nrf_radio_bcc_set(num_data_bytes * 8); - } - else - { - m_flags.frame_filtered = true; - } - } - else if ((filter_result == NRF_802154_RX_ERROR_INVALID_LENGTH) || - (!nrf_802154_pib_promiscuous_get())) + if (listening_end_timestamp - m_listening_start_hp_timestamp >= MAX_PHY_FRAME_TIME_US) { - rx_terminate(); - rx_init(true); + /* m_listening_start_hp_timestamp ... now - MAX_PHY_FRAME_TIME_US must be listening. + * Last MAX_PHY_FRAME_TIME_US is considered uncertain. + */ + listening_end_timestamp -= MAX_PHY_FRAME_TIME_US; - frame_accepted = false; + uint32_t t_listening = listening_end_timestamp - m_listening_start_hp_timestamp; - if ((mp_current_rx_buffer->data[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) != - FRAME_TYPE_ACK) - { - receive_failed_notify(filter_result); - } + m_listening_start_hp_timestamp = listening_end_timestamp; + + nrf_802154_stat_totals_increment(total_listening_time, t_listening); } else { - // Promiscuous mode, allow incorrect frames. Nothing to do here. + /* Too little time passed since m_listening_start_hp_timestamp, we don't know + * if frame is being received now until it is received. */ } } - if ((!m_flags.rx_timeslot_requested) && (frame_accepted)) - { - if (nrf_802154_rsch_timeslot_request(nrf_802154_rx_duration_get( - mp_current_rx_buffer->data[0], - ack_is_requested(mp_current_rx_buffer->data)))) - { - m_flags.rx_timeslot_requested = true; - - receive_started_notify(); - } - else - { - // Disable receiver and wait for a new timeslot. - rx_terminate(); + nrf_802154_mcu_critical_exit(mcu_cs); - nrf_802154_notify_receive_failed(NRF_802154_RX_ERROR_TIMESLOT_ENDED); - } - } } -#endif // !NRF_802154_DISABLE_BCC_MATCHING +#endif -#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR -static void irq_crcerror_state_rx(void) +void nrf_802154_trx_receive_frame_crcerror(void) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED + uint32_t receive_end_hp_timestamp = nrf_802154_hp_timer_timestamp_get(); + uint32_t listening_start_hp_timestamp = m_listening_start_hp_timestamp; + +#endif + + assert(m_state == RADIO_STATE_RX); + rx_flags_clear(); + + // We don't change receive buffer, receive will go to the same that was already used #if !NRF_802154_DISABLE_BCC_MATCHING - rx_restart(false); -#endif // !NRF_802154_DISABLE_BCC_MATCHING + request_preconditions_for_state(m_state); + nrf_802154_trx_receive_frame(BCC_INIT / 8U, m_trx_receive_frame_notifications_mask); + +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED + m_listening_start_hp_timestamp = nrf_802154_hp_timer_current_time_get(); + + // Configure the timer coordinator to get a timestamp of the END event which + // fires several cycles after CRCOK or CRCERROR events. + nrf_802154_timer_coord_timestamp_prepare( + nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_END)); +#endif + +#else + // With BCC matching disabled trx module will re-arm automatically +#endif + +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED + update_total_times_on_receive_end(listening_start_hp_timestamp, receive_end_hp_timestamp, + mp_current_rx_buffer->data[PHR_OFFSET]); +#endif + #if NRF_802154_NOTIFY_CRCERROR receive_failed_notify(NRF_802154_RX_ERROR_INVALID_FCS); #endif // NRF_802154_NOTIFY_CRCERROR + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } -#endif // !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR +void nrf_802154_trx_receive_ack_crcerror(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert(m_state == RADIO_STATE_RX_ACK); + +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED + uint32_t receive_end_hp_timestamp = nrf_802154_hp_timer_timestamp_get(); + uint32_t listening_start_hp_timestamp = m_listening_start_hp_timestamp; + + update_total_times_on_receive_end(listening_start_hp_timestamp, receive_end_hp_timestamp, + mp_current_rx_buffer->data[PHR_OFFSET]); +#endif + + on_bad_ack(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} -static void irq_crcok_state_rx(void) +void nrf_802154_trx_receive_frame_received(void) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + uint8_t * p_received_data = mp_current_rx_buffer->data; - uint32_t ints_to_disable = 0; - uint32_t ints_to_enable = 0; - m_flags.rssi_started = true; +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED + uint32_t receive_end_hp_timestamp = nrf_802154_hp_timer_timestamp_get(); + uint32_t listening_start_hp_timestamp = m_listening_start_hp_timestamp; + + update_total_times_on_receive_end(listening_start_hp_timestamp, receive_end_hp_timestamp, + mp_current_rx_buffer->data[PHR_OFFSET]); +#endif #if NRF_802154_DISABLE_BCC_MATCHING uint8_t num_data_bytes = PHR_SIZE + FCF_SIZE; @@ -2118,7 +1815,7 @@ static void irq_crcok_state_rx(void) { // Frame is destined to this node but there is no timeslot to transmit ACK. // Just disable receiver and wait for a new timeslot. - rx_terminate(); + nrf_802154_trx_abort(); rx_flags_clear(); @@ -2130,12 +1827,23 @@ static void irq_crcok_state_rx(void) received_frame_notify_and_nesting_allow(p_received_data); } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return; } #endif // NRF_802154_DISABLE_BCC_MATCHING if (m_flags.frame_filtered || nrf_802154_pib_promiscuous_get()) { + nrf_802154_stat_counter_increment(received_frames); + +#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) + uint32_t ts = timer_coord_timestamp_get(); + + nrf_802154_stat_timestamp_write(last_rx_end_timestamp, ts); +#endif + + nrf_802154_sl_ant_div_rx_frame_received_notify(); + bool send_ack = false; if (m_flags.frame_filtered && @@ -2151,154 +1859,61 @@ static void irq_crcok_state_rx(void) if (send_ack) { - bool wait_for_phyend; - - nrf_radio_packetptr_set(mp_ack); - - // Set shorts - nrf_radio_shorts_set(SHORTS_TX_ACK); - - // Clear TXREADY event to detect if PPI worked - nrf_radio_event_clear(NRF_RADIO_EVENT_TXREADY); - -#if NRF_802154_DISABLE_BCC_MATCHING - // Disable PPIs for PSDU detection - nrf_ppi_fork_endpoint_setup(PPI_EGU_TIMER_START, 0); - nrf_ppi_channel_disable(PPI_ADDRESS_COUNTER_COUNT); - nrf_ppi_channel_disable(PPI_CRCERROR_COUNTER_CLEAR); -#endif // NRF_802154_DISABLE_BCC_MATCHING - - // Set PPIs - nrf_ppi_channel_endpoint_setup(PPI_TIMER_TX_ACK, - (uint32_t)nrf_timer_event_address_get( - NRF_802154_TIMER_INSTANCE, - NRF_TIMER_EVENT_COMPARE1), - (uint32_t)nrf_radio_task_address_get( - NRF_RADIO_TASK_TXEN)); - -#if !NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_enable(PPI_TIMER_TX_ACK); -#endif // !NRF_802154_DISABLE_BCC_MATCHING - - // Set FEM PPIs - uint32_t time_to_rampup = nrf_timer_cc_read(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_CC_CHANNEL1); - - nrf_802154_fal_event_t timer = m_activate_tx_cc0; - - timer.event.timer.counter_value += time_to_rampup; + state_set(RADIO_STATE_TX_ACK); - nrf_802154_fal_pa_configuration_set(&timer, NULL); - - // Detect if PPI worked (timer is counting or TIMER event is marked) - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_CAPTURE3); - uint32_t current_timer_value = nrf_timer_cc_read(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_CC_CHANNEL3); - uint32_t time_to_fem = nrf_timer_cc_read(NRF_802154_TIMER_INSTANCE, - NRF_TIMER_CC_CHANNEL0); - - // When external PA uses timer, it should be configured to a time later than ramp up - // time. In such case, the timer stops with shorts on PA timer. - // But if external PA does not use timer, FEM time is set to a value in the pased - // used by LNA. After timer overflow, the timer stops with short on the past value - // used by LNA. We have to detect if the timer is after the overflow. - if ((current_timer_value < time_to_rampup) && - ((time_to_fem >= time_to_rampup) || (current_timer_value > time_to_fem))) - { - wait_for_phyend = true; - } - else + if (is_state_allowed_for_prio(m_rsch_priority, RADIO_STATE_TX_ACK)) { - ppi_and_egu_delay_wait(); - - if (nrf_radio_state_get() == NRF_RADIO_STATE_TXRU) - { - wait_for_phyend = true; - } - else if (nrf_radio_event_check(NRF_RADIO_EVENT_TXREADY)) + if (nrf_802154_trx_transmit_ack(mp_ack, ACK_IFS)) { - wait_for_phyend = true; + // Intentionally empty: transmitting ack, because we can } else { - wait_for_phyend = false; - } - } - - if (wait_for_phyend) - { - state_set(RADIO_STATE_TX_ACK); + mp_current_rx_buffer->free = false; - // Set event handlers -#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR - ints_to_disable |= NRF_RADIO_INT_CRCERROR_MASK; -#endif // !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR -#if !NRF_802154_DISABLE_BCC_MATCHING - ints_to_disable |= NRF_RADIO_INT_BCMATCH_MASK; -#endif // !NRF_802154_DISABLE_BCC_MATCHING - ints_to_disable |= NRF_RADIO_INT_CRCOK_MASK; - nrf_radio_int_disable(ints_to_disable); - - nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); - ints_to_enable = NRF_RADIO_INT_PHYEND_MASK; - -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - nrf_radio_event_clear(NRF_RADIO_EVENT_ADDRESS); - ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED + state_set(RADIO_STATE_RX); + rx_init(); - nrf_radio_int_enable(ints_to_enable); + received_frame_notify_and_nesting_allow(p_received_data); + } } else { - mp_current_rx_buffer->free = false; + if (!nrf_802154_rsch_prec_is_approved(RSCH_PREC_COEX, + min_required_rsch_prio(RADIO_STATE_TX_ACK))) + { + nrf_802154_stat_counter_increment(coex_denied_requests); + } -#if !NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_disable(PPI_TIMER_TX_ACK); - nrf_ppi_channel_endpoint_setup(PPI_TIMER_TX_ACK, 0, 0); - nrf_ppi_fork_endpoint_setup(PPI_TIMER_TX_ACK, 0); -#endif // !NRF_802154_DISABLE_BCC_MATCHING + mp_current_rx_buffer->free = false; - // RX uses the same peripherals as TX_ACK until RADIO ints are updated. - rx_terminate(); - rx_init(true); + state_set(RADIO_STATE_RX); + rx_init(); received_frame_notify_and_nesting_allow(p_received_data); } } else { - rx_restart(true); - + request_preconditions_for_state(m_state); // Filter out received ACK frame if promiscuous mode is disabled. if (((p_received_data[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) != FRAME_TYPE_ACK) || nrf_802154_pib_promiscuous_get()) { - // Find new RX buffer + // Current buffer will be passed to the application mp_current_rx_buffer->free = false; - rx_buffer_in_use_set(nrf_802154_rx_buffer_free_find()); - if (rx_buffer_is_available()) - { - nrf_radio_packetptr_set(rx_buffer_get()); - nrf_radio_shorts_set(SHORTS_RX | SHORTS_RX_FREE_BUFFER); + // Find new buffer + rx_buffer_in_use_set(nrf_802154_rx_buffer_free_find()); - if (nrf_radio_state_get() == NRF_RADIO_STATE_RXIDLE) - { - nrf_radio_task_trigger(NRF_RADIO_TASK_START); - } - } + rx_init(); received_frame_notify_and_nesting_allow(p_received_data); } else { - nrf_radio_shorts_set(SHORTS_RX | SHORTS_RX_FREE_BUFFER); - - if (nrf_radio_state_get() == NRF_RADIO_STATE_RXIDLE) - { - nrf_radio_task_trigger(NRF_RADIO_TASK_START); - } + // Receive to the same buffer + rx_init(); } } } @@ -2307,8 +1922,8 @@ static void irq_crcok_state_rx(void) // CRC is OK, but filtering operation did not end - it is invalid frame with valid CRC // or problem due to software latency (i.e. handled BCMATCH, CRCERROR, CRCOK from two // consecutively received frames). - rx_terminate(); - rx_init(true); + request_preconditions_for_state(m_state); + rx_init(); #if NRF_802154_DISABLE_BCC_MATCHING if ((p_received_data[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) != FRAME_TYPE_ACK) @@ -2319,572 +1934,397 @@ static void irq_crcok_state_rx(void) receive_failed_notify(NRF_802154_RX_ERROR_RUNTIME); #endif // NRF_802154_DISABLE_BCC_MATCHING } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } -static void irq_phyend_state_tx_ack(void) +void nrf_802154_trx_transmit_frame_started(void) { - uint8_t * p_received_data = mp_current_rx_buffer->data; - uint32_t ints_to_enable = 0; - uint32_t ints_to_disable = 0; - - // Disable PPIs on DISABLED event to control TIMER. - nrf_ppi_channel_disable(PPI_DISABLED_EGU); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - // Set FEM PPIs - nrf_802154_fal_pa_configuration_clear(&m_activate_tx_cc0, NULL); - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); - nrf_802154_fal_lna_configuration_set(&m_activate_rx_cc0, NULL); - - nrf_radio_shorts_set(SHORTS_RX); + assert((m_state == RADIO_STATE_TX) || (m_state == RADIO_STATE_CCA_TX)); + transmit_started_notify(); - // Set BCC for next reception -#if !NRF_802154_DISABLE_BCC_MATCHING - nrf_radio_bcc_set(BCC_INIT); -#endif // !NRF_802154_DISABLE_BCC_MATCHING + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} - ints_to_disable = NRF_RADIO_INT_PHYEND_MASK; +void nrf_802154_trx_transmit_ack_started(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - ints_to_disable |= NRF_RADIO_INT_ADDRESS_MASK; -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED + assert(m_state == RADIO_STATE_TX_ACK); + nrf_802154_tx_ack_started(mp_ack); - nrf_radio_int_disable(ints_to_disable); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} -#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR - nrf_radio_event_clear(NRF_RADIO_EVENT_CRCERROR); - ints_to_enable |= NRF_RADIO_INT_CRCERROR_MASK; -#endif // !NRF_802154_DISABLE_BCC_MATCHING ||NRF_802154_NOTIFY_CRCERROR -#if !NRF_802154_DISABLE_BCC_MATCHING - nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); - ints_to_enable |= NRF_RADIO_INT_BCMATCH_MASK; -#endif // !NRF_802154_DISABLE_BCC_MATCHING - nrf_radio_event_clear(NRF_RADIO_EVENT_CRCOK); - ints_to_enable |= NRF_RADIO_INT_CRCOK_MASK; - nrf_radio_int_enable(ints_to_enable); +void nrf_802154_trx_transmit_ack_transmitted(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - // Restart TIMER. - // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. - nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + assert(m_state == RADIO_STATE_TX_ACK); -#if NRF_802154_DISABLE_BCC_MATCHING - // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. - nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + uint32_t t_transmit = TX_RAMP_UP_TIME + nrf_802154_frame_duration_get(mp_ack[PHR_OFFSET], + true, + true); - // Reset PPI for RX mode -#if PPI_TIMER_TX_ACK != PPI_CRCERROR_CLEAR -#error Invalid PPI configuration + nrf_802154_stat_totals_increment(total_transmit_time, t_transmit); #endif - // Anomaly 78: use SHUTDOWN instead of CLEAR. - nrf_ppi_channel_endpoint_setup(PPI_CRCERROR_CLEAR, - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCERROR), - (uint32_t)nrf_timer_task_address_get( - NRF_802154_TIMER_INSTANCE, - NRF_TIMER_TASK_SHUTDOWN)); - - nrf_ppi_fork_endpoint_setup(PPI_EGU_TIMER_START, - (uint32_t)nrf_timer_task_address_get( - NRF_802154_COUNTER_TIMER_INSTANCE, - NRF_TIMER_TASK_START)); -#else // NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_disable(PPI_TIMER_TX_ACK); - nrf_ppi_channel_endpoint_setup(PPI_TIMER_TX_ACK, 0, 0); - nrf_ppi_fork_endpoint_setup(PPI_TIMER_TX_ACK, 0); -#endif // NRF_802154_DISABLE_BCC_MATCHING - - // Enable PPI disabled by CRCOK - nrf_ppi_channel_enable(PPI_EGU_RAMP_UP); -#if NRF_802154_DISABLE_BCC_MATCHING - nrf_ppi_channel_enable(PPI_ADDRESS_COUNTER_COUNT); - nrf_ppi_channel_enable(PPI_CRCERROR_COUNTER_CLEAR); -#endif // NRF_802154_DISABLE_BCC_MATCHING - - // Enable PPIs on DISABLED event and clear event to detect if PPI worked - nrf_egu_event_clear(NRF_802154_SWI_EGU_INSTANCE, EGU_EVENT); - nrf_ppi_channel_enable(PPI_DISABLED_EGU); - // Prepare the timer coordinator to get a precise timestamp of the CRCOK event. - nrf_802154_timer_coord_timestamp_prepare( - (uint32_t)nrf_radio_event_address_get(NRF_RADIO_EVENT_CRCOK)); - - if (!ppi_egu_worked()) - { - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - } + uint8_t * p_received_data = mp_current_rx_buffer->data; - // Find new RX buffer + // Current buffer used for receive operation will be passed to the application mp_current_rx_buffer->free = false; - rx_buffer_in_use_set(nrf_802154_rx_buffer_free_find()); - - if (rx_buffer_is_available()) - { - nrf_radio_packetptr_set(rx_buffer_get()); - nrf_radio_shorts_set(SHORTS_RX | SHORTS_RX_FREE_BUFFER); - - if (nrf_radio_state_get() == NRF_RADIO_STATE_RXIDLE) - { - nrf_radio_task_trigger(NRF_RADIO_TASK_START); - } - } state_set(RADIO_STATE_RX); - rx_flags_clear(); + rx_init(); received_frame_notify_and_nesting_allow(p_received_data); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } -static void irq_phyend_state_tx_frame(void) +void nrf_802154_trx_transmit_frame_transmitted(void) { - uint32_t ints_to_disable = 0; - uint32_t ints_to_enable = 0; - - // Ignore PHYEND event if transmission has not started. This event may be triggered by - // previously terminated transmission. - if (!transmission_has_started()) - { - return; - } + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - if (ack_is_requested(mp_tx_data)) - { - bool rx_buffer_free = rx_buffer_is_available(); - uint32_t shorts = rx_buffer_free ? - (SHORTS_RX_ACK | SHORTS_RX_FREE_BUFFER) : SHORTS_RX_ACK; +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + uint32_t t_listening = 0U; + uint32_t t_transmit = 0U; - // Disable EGU PPI to prevent unsynchronized PPIs - nrf_ppi_channel_disable(PPI_DISABLED_EGU); +#endif - nrf_radio_shorts_set(shorts); +#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) + uint32_t ts = timer_coord_timestamp_get(); - if (rx_buffer_free) - { - nrf_radio_packetptr_set(rx_buffer_get()); - } + // ts holds now timestamp of the PHYEND event + nrf_802154_stat_timestamp_write(last_tx_end_timestamp, ts); - ints_to_disable = NRF_RADIO_INT_CCABUSY_MASK; -#if NRF_802154_TX_STARTED_NOTIFY_ENABLED - ints_to_disable |= NRF_RADIO_INT_ADDRESS_MASK; -#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED + if (m_flags.tx_with_cca) + { + m_flags.tx_diminished_prio = false; - ints_to_disable |= NRF_RADIO_INT_PHYEND_MASK; - nrf_radio_event_clear(NRF_RADIO_EVENT_END); - ints_to_enable |= NRF_RADIO_INT_END_MASK; + // We calculate the timestamp when ccaidle must happened. + ts -= nrf_802154_frame_duration_get(mp_tx_data[0], true, true) + RX_TX_TURNAROUND_TIME; - nrf_radio_int_disable(ints_to_disable); + nrf_802154_stat_timestamp_write(last_cca_idle_timestamp, ts); - nrf_radio_event_clear(NRF_RADIO_EVENT_ADDRESS); - ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + t_listening += RX_RAMP_UP_TIME + + (ts - nrf_802154_stat_timestamp_read(last_cca_start_timestamp)); + t_transmit += RX_TX_TURNAROUND_TIME; +#endif + } + else + { +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + t_transmit += TX_RAMP_UP_TIME; +#endif + } - nrf_radio_int_enable(ints_to_enable); +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + t_transmit += nrf_802154_frame_duration_get(mp_tx_data[PHR_OFFSET], true, true); - // Clear FEM configuration set at the beginning of the transmission - fem_for_tx_reset(false); - // Set PPIs necessary in rx_ack state - fem_for_lna_set(); + nrf_802154_stat_totals_increment(total_listening_time, t_listening); + nrf_802154_stat_totals_increment(total_transmit_time, t_transmit); +#endif +#endif - nrf_ppi_channel_and_fork_endpoint_setup(PPI_EGU_RAMP_UP, - (uint32_t)nrf_egu_event_address_get( - NRF_802154_SWI_EGU_INSTANCE, - EGU_EVENT), - (uint32_t)nrf_radio_task_address_get( - NRF_RADIO_TASK_RXEN), - (uint32_t)nrf_ppi_task_address_get( - PPI_CHGRP0_DIS_TASK)); + if (ack_is_requested(mp_tx_data)) + { + state_set(RADIO_STATE_RX_ACK); - nrf_egu_event_clear(NRF_802154_SWI_EGU_INSTANCE, EGU_EVENT); + bool rx_buffer_free = rx_buffer_is_available(); - // Enable PPI disabled by DISABLED event - nrf_ppi_channel_enable(PPI_EGU_RAMP_UP); + nrf_802154_trx_receive_buffer_set(rx_buffer_get()); - // Enable EGU PPI to start all PPIs synchronously - nrf_ppi_channel_enable(PPI_DISABLED_EGU); +#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + // Configure the timer coordinator to get a timestamp of the END event which + // fires several cycles after CRCOK or CRCERROR events. + nrf_802154_timer_coord_timestamp_prepare( + nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_END)); +#else + // Configure the timer coordinator to get a timestamp of the CRCOK event. + nrf_802154_timer_coord_timestamp_prepare(nrf_radio_event_address_get(NRF_RADIO, + NRF_RADIO_EVENT_CRCOK)); +#endif +#endif - state_set(RADIO_STATE_RX_ACK); + nrf_802154_trx_receive_ack(); - if (!ppi_egu_worked()) - { - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); - } +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED + m_listening_start_hp_timestamp = nrf_802154_hp_timer_current_time_get(); +#endif if (!rx_buffer_free) { rx_buffer_in_use_set(nrf_802154_rx_buffer_free_find()); - if (rx_buffer_is_available()) - { - nrf_radio_packetptr_set(rx_buffer_get()); - nrf_radio_shorts_set(SHORTS_RX_ACK | SHORTS_RX_FREE_BUFFER); - - if (nrf_radio_state_get() == NRF_RADIO_STATE_RXIDLE) - { - nrf_radio_task_trigger(NRF_RADIO_TASK_START); - } - } - } - - if ((mp_tx_data[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK) != FRAME_VERSION_2) - { - ack_matching_enable(); + nrf_802154_trx_receive_buffer_set(rx_buffer_get()); } } else { - tx_terminate(); state_set(RADIO_STATE_RX); - rx_init(true); + + rx_init(); transmitted_frame_notify(NULL, 0, 0); } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } -static void irq_end_state_rx_ack(void) +static bool ack_match_check_version_not_2(const uint8_t * p_tx_data, const uint8_t * p_ack_data) { - bool ack_match = ack_is_matched(); - rx_buffer_t * p_ack_buffer = NULL; - uint8_t * p_ack_data = mp_current_rx_buffer->data; + // Frame Version != 2 - if (!ack_match && - ((mp_tx_data[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK) == FRAME_VERSION_2) && - ((p_ack_data[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK) == FRAME_VERSION_2) && - ((p_ack_data[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) == FRAME_TYPE_ACK) && - (nrf_radio_crc_status_check())) + // Check: Phy length + if (p_ack_data[PHR_OFFSET] != IMM_ACK_LENGTH) { - // For frame version 2 sequence number bit may be suppressed and its check fails. - // Verify ACK frame using its destination address. - nrf_802154_frame_parser_mhr_data_t tx_mhr_data; - nrf_802154_frame_parser_mhr_data_t ack_mhr_data; - bool parse_result; - - parse_result = nrf_802154_frame_parser_mhr_parse(mp_tx_data, &tx_mhr_data); - assert(parse_result); - parse_result = nrf_802154_frame_parser_mhr_parse(p_ack_data, &ack_mhr_data); - - if (parse_result && - (tx_mhr_data.p_src_addr != NULL) && - (ack_mhr_data.p_dst_addr != NULL) && - (tx_mhr_data.src_addr_size == ack_mhr_data.dst_addr_size) && - (0 == memcmp(tx_mhr_data.p_src_addr, - ack_mhr_data.p_dst_addr, - tx_mhr_data.src_addr_size))) - { - ack_match = true; - } + return false; } - if (ack_match) + // Check if Frame version is 0 or 1. + switch (p_ack_data[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK) { - p_ack_buffer = mp_current_rx_buffer; - mp_current_rx_buffer->free = false; - } - - rx_ack_terminate(); - state_set(RADIO_STATE_RX); - rx_init(true); + case FRAME_VERSION_0: + case FRAME_VERSION_1: + break; - if (ack_match) - { - transmitted_frame_notify(p_ack_buffer->data, // phr + psdu - rssi_last_measurement_get(), // rssi - lqi_get(p_ack_buffer->data)); // lqi; + default: + return false; } - else + + // Check: Sequence number match + if (p_ack_data[DSN_OFFSET] != p_tx_data[DSN_OFFSET]) { - transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_INVALID_ACK); + return false; } -} -static void irq_disabled_state_falling_asleep(void) -{ - falling_asleep_terminate(); - state_set(RADIO_STATE_SLEEP); - sleep_init(); + return true; } -/// This event is generated when CCA reports idle channel during stand-alone procedure. -static void irq_ccaidle_state_cca(void) +static bool ack_match_check_version_2(const uint8_t * p_tx_data, const uint8_t * p_ack_data) { - cca_terminate(); - state_set(RADIO_STATE_RX); - rx_init(true); - - cca_notify(true); -} + if ((p_ack_data[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK) != FRAME_VERSION_2) + { + return false; + } -static void irq_ccabusy_state_tx_frame(void) -{ - tx_terminate(); - state_set(RADIO_STATE_RX); - rx_init(true); + // Transmitted frame was Version 2 + // For frame version 2 sequence number bit may be suppressed and its check fails. + // Verify ACK frame using its destination address. + nrf_802154_frame_parser_mhr_data_t tx_mhr_data; + nrf_802154_frame_parser_mhr_data_t ack_mhr_data; + bool parse_result; - transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_BUSY_CHANNEL); -} + parse_result = nrf_802154_frame_parser_mhr_parse(p_tx_data, &tx_mhr_data); + assert(parse_result); + parse_result = nrf_802154_frame_parser_mhr_parse(p_ack_data, &ack_mhr_data); -static void irq_ccabusy_state_cca(void) -{ - cca_terminate(); - state_set(RADIO_STATE_RX); - rx_init(true); + if (!parse_result || + (tx_mhr_data.p_src_addr == NULL) || + (ack_mhr_data.p_dst_addr == NULL) || + (tx_mhr_data.src_addr_size != ack_mhr_data.dst_addr_size) || + (0 != memcmp(tx_mhr_data.p_src_addr, + ack_mhr_data.p_dst_addr, + tx_mhr_data.src_addr_size))) + { + // Mismatch + return false; + } - cca_notify(false); + return true; } -/// This event is generated when energy detection procedure ends. -static void irq_edend_state_ed(void) +static bool ack_match_check(const uint8_t * p_tx_data, const uint8_t * p_ack_data) { - uint32_t result = nrf_radio_ed_sample_get(); - - m_ed_result = result > m_ed_result ? result : m_ed_result; - - if (m_ed_time_left) + if ((p_tx_data == NULL) || (p_ack_data == NULL)) { - if (ed_iter_setup(m_ed_time_left)) - { - nrf_radio_task_trigger(NRF_RADIO_TASK_EDSTART); - } - else - { - fem_for_lna_reset(); - } + return false; } - else - { - // In case channel change was requested during energy detection procedure. - channel_set(nrf_802154_pib_channel_get()); - ed_terminate(); - state_set(RADIO_STATE_RX); - rx_init(true); - - energy_detected_notify(ed_result_get()); + // Check: Frame Control Field -> Frame type + if ((p_ack_data[FRAME_TYPE_OFFSET] & FRAME_TYPE_MASK) != FRAME_TYPE_ACK) + { + return false; // This is not an ACK frame } -} -/// Handler of radio interrupts. -static void irq_handler(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_IRQ_HANDLER); - - // Prevent interrupting of this handler by requests from higher priority code. - nrf_802154_critical_section_forcefully_enter(); - - if (nrf_radio_int_enable_check(NRF_RADIO_INT_ADDRESS_MASK) && - nrf_radio_event_check(NRF_RADIO_EVENT_ADDRESS)) + // Check: Frame Control Field -> Frame version + if ((p_tx_data[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK) == FRAME_VERSION_2) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_FRAMESTART); - nrf_radio_event_clear(NRF_RADIO_EVENT_ADDRESS); + return ack_match_check_version_2(p_tx_data, p_ack_data); + } - switch (m_state) - { - case RADIO_STATE_CCA_TX: - case RADIO_STATE_TX: - irq_address_state_tx_frame(); - break; + return ack_match_check_version_not_2(p_tx_data, p_ack_data); +} - case RADIO_STATE_TX_ACK: - irq_address_state_tx_ack(); - break; +static void on_bad_ack(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - case RADIO_STATE_RX_ACK: - irq_address_state_rx_ack(); - break; + // We received either a frame with incorrect CRC or not an ACK frame or not matching ACK + state_set(RADIO_STATE_RX); - default: - assert(false); - } + rx_init(); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_FRAMESTART); - } + transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_INVALID_ACK); -#if !NRF_802154_DISABLE_BCC_MATCHING - // Check MAC frame header. - if (nrf_radio_int_enable_check(NRF_RADIO_INT_BCMATCH_MASK) && - nrf_radio_event_check(NRF_RADIO_EVENT_BCMATCH)) - { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_BCMATCH); - nrf_radio_event_clear(NRF_RADIO_EVENT_BCMATCH); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} - switch (m_state) - { - case RADIO_STATE_RX: - irq_bcmatch_state_rx(); - break; +void nrf_802154_trx_receive_ack_received(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - default: - assert(false); - } + // CRC of received frame is correct + uint8_t * p_ack_data = mp_current_rx_buffer->data; - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_BCMATCH); - } +#if NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED + uint32_t receive_end_hp_timestamp = nrf_802154_hp_timer_timestamp_get(); + uint32_t listening_start_hp_timestamp = m_listening_start_hp_timestamp; -#endif // !NRF_802154_DISABLE_BCC_MATCHING + update_total_times_on_receive_end(listening_start_hp_timestamp, receive_end_hp_timestamp, + mp_current_rx_buffer->data[PHR_OFFSET]); +#endif -#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR - if (nrf_radio_int_enable_check(NRF_RADIO_INT_CRCERROR_MASK) && - nrf_radio_event_check(NRF_RADIO_EVENT_CRCERROR)) + if (ack_match_check(mp_tx_data, p_ack_data)) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_CRCERROR); - nrf_radio_event_clear(NRF_RADIO_EVENT_CRCERROR); +#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) + uint32_t ts = timer_coord_timestamp_get(); - switch (m_state) - { - case RADIO_STATE_RX: - irq_crcerror_state_rx(); - break; + nrf_802154_stat_timestamp_write(last_ack_end_timestamp, ts); +#endif - default: - assert(false); - } + rx_buffer_t * p_ack_buffer = mp_current_rx_buffer; - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_CRCERROR); - } -#endif // !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR + mp_current_rx_buffer->free = false; - if (nrf_radio_int_enable_check(NRF_RADIO_INT_CRCOK_MASK) && - nrf_radio_event_check(NRF_RADIO_EVENT_CRCOK)) + state_set(RADIO_STATE_RX); + rx_init(); + + transmitted_frame_notify(p_ack_buffer->data, // phr + psdu + rssi_last_measurement_get(), // rssi + lqi_get(p_ack_buffer->data)); // lqi; + } + else { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_CRCOK); - nrf_radio_event_clear(NRF_RADIO_EVENT_CRCOK); + on_bad_ack(); + } - switch (m_state) - { - case RADIO_STATE_RX: - irq_crcok_state_rx(); - break; + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} - default: - assert(false); - } +void nrf_802154_trx_standalone_cca_finished(bool channel_was_idle) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_CRCOK); - } + state_set(RADIO_STATE_RX); + rx_init(); - if (nrf_radio_int_enable_check(NRF_RADIO_INT_PHYEND_MASK) && - nrf_radio_event_check(NRF_RADIO_EVENT_PHYEND)) - { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_PHYEND); - nrf_radio_event_clear(NRF_RADIO_EVENT_PHYEND); + cca_notify(channel_was_idle); - switch (m_state) - { - case RADIO_STATE_TX_ACK: - irq_phyend_state_tx_ack(); - break; + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} - case RADIO_STATE_CCA_TX: - case RADIO_STATE_TX: - irq_phyend_state_tx_frame(); - break; +void nrf_802154_trx_transmit_frame_ccastarted(void) +{ + // This handler provided by trx is never called because parameter notifications_mask + // of the nrf_802154_trx_transmit_frame does not contain TRX_TRANSMIT_NOTIFICATION_CCASTARTED. + assert(false); +} - default: - assert(false); - } +void nrf_802154_trx_transmit_frame_ccaidle(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_PHYEND); - } + assert(m_state == RADIO_STATE_CCA_TX); + assert(m_trx_transmit_frame_notifications_mask & TRX_TRANSMIT_NOTIFICATION_CCAIDLE); - if (nrf_radio_int_enable_check(NRF_RADIO_INT_END_MASK) && - nrf_radio_event_check(NRF_RADIO_EVENT_END)) - { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_END); - nrf_radio_event_clear(NRF_RADIO_EVENT_END); +#if (NRF_802154_FRAME_TIMESTAMP_ENABLED) + uint32_t ts = timer_coord_timestamp_get(); - switch (m_state) - { - case RADIO_STATE_RX_ACK: // Ended receiving of ACK. - irq_end_state_rx_ack(); - break; + // Configure the timer coordinator to get a timestamp of the PHYEND event. + nrf_802154_timer_coord_timestamp_prepare(nrf_radio_event_address_get(NRF_RADIO, + NRF_RADIO_EVENT_PHYEND)); - default: - assert(false); - } + // Update stat timestamp of CCASTART event + nrf_802154_stat_timestamp_write(last_cca_start_timestamp, ts); +#endif - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_END); + if (m_coex_tx_request_mode == NRF_802154_COEX_TX_REQUEST_MODE_CCA_DONE) + { + nrf_802154_rsch_crit_sect_prio_request(RSCH_PRIO_TX); + m_flags.tx_diminished_prio = false; } - if (nrf_radio_int_enable_check(NRF_RADIO_INT_DISABLED_MASK) && - nrf_radio_event_check(NRF_RADIO_EVENT_DISABLED)) - { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_DISABLED); - nrf_radio_event_clear(NRF_RADIO_EVENT_DISABLED); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} - switch (m_state) - { - case RADIO_STATE_FALLING_ASLEEP: - irq_disabled_state_falling_asleep(); - break; +void nrf_802154_trx_transmit_frame_ccabusy(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - default: - assert(false); - } + nrf_802154_stat_counter_increment(cca_failed_attempts); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_DISABLED); - } +#if (NRF_802154_TOTAL_TIMES_MEASUREMENT_ENABLED) + uint32_t t_listening = RX_RAMP_UP_TIME + PHY_US_TIME_FROM_SYMBOLS(A_CCA_DURATION_SYMBOLS); - if (nrf_radio_int_enable_check(NRF_RADIO_INT_CCAIDLE_MASK) && - nrf_radio_event_check(NRF_RADIO_EVENT_CCAIDLE)) - { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_CCAIDLE); - nrf_radio_event_clear(NRF_RADIO_EVENT_CCAIDLE); + nrf_802154_stat_totals_increment(total_listening_time, t_listening); +#endif - switch (m_state) - { - case RADIO_STATE_CCA: - irq_ccaidle_state_cca(); - break; + state_set(RADIO_STATE_RX); + rx_init(); - default: - assert(false); - } + transmit_failed_notify_and_nesting_allow(NRF_802154_TX_ERROR_BUSY_CHANNEL); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_CCAIDLE); +void nrf_802154_trx_energy_detection_finished(uint8_t ed_sample) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + if (m_ed_result < ed_sample) + { + // Collect maximum value of samples provided by trx + m_ed_result = ed_sample; } - if (nrf_radio_int_enable_check(NRF_RADIO_INT_CCABUSY_MASK) && - nrf_radio_event_check(NRF_RADIO_EVENT_CCABUSY)) + if (m_ed_time_left >= ED_ITER_DURATION) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_CCABUSY); - nrf_radio_event_clear(NRF_RADIO_EVENT_CCABUSY); + uint32_t trx_ed_count = 0U; - switch (m_state) + if (ed_iter_setup(&m_ed_time_left, &trx_ed_count)) { - case RADIO_STATE_CCA_TX: - case RADIO_STATE_TX: - irq_ccabusy_state_tx_frame(); - break; - - case RADIO_STATE_CCA: - irq_ccabusy_state_cca(); - break; - - default: - assert(false); + nrf_802154_trx_energy_detection(trx_ed_count); + } + else + { + /* There is too little time in current timeslot, just wait for timeslot end. + * Operation will be resumed in next timeslot */ } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_CCABUSY); } - - if (nrf_radio_int_enable_check(NRF_RADIO_INT_EDEND_MASK) && - nrf_radio_event_check(NRF_RADIO_EVENT_EDEND)) + else if (nrf_802154_sl_ant_div_energy_detection_finished_notify()) + { + ed_init(); + } + else { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_EVENT_EDEND); - nrf_radio_event_clear(NRF_RADIO_EVENT_EDEND); + nrf_802154_trx_channel_set(nrf_802154_pib_channel_get()); - switch (m_state) - { - case RADIO_STATE_ED: - irq_edend_state_ed(); - break; + state_set(RADIO_STATE_RX); + rx_init(); - default: - assert(false); - } + energy_detected_notify(ed_result_get(m_ed_result)); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_EVENT_EDEND); } - nrf_802154_critical_section_exit(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_IRQ_HANDLER); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } /*************************************************************************************************** @@ -2896,21 +2336,25 @@ void nrf_802154_core_init(void) m_state = RADIO_STATE_SLEEP; m_rsch_timeslot_is_granted = false; - nrf_timer_init(); + nrf_802154_trx_init(); nrf_802154_ack_generator_init(); } void nrf_802154_core_deinit(void) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + if (timeslot_is_granted()) { - nrf_radio_reset(); - nrf_802154_fal_deactivate_now(NRF_802154_FAL_ALL); + nrf_802154_trx_disable(); } nrf_802154_fal_cleanup(); - irq_deinit(); + nrf_802154_irq_disable(RADIO_IRQn); + nrf_802154_irq_clear_pending(RADIO_IRQn); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } radio_state_t nrf_802154_core_state_get(void) @@ -2920,6 +2364,8 @@ radio_state_t nrf_802154_core_state_get(void) bool nrf_802154_core_sleep(nrf_802154_term_t term_lvl) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result = nrf_802154_critical_section_enter(); if (result) @@ -2930,14 +2376,25 @@ bool nrf_802154_core_sleep(nrf_802154_term_t term_lvl) if (result) { - state_set(RADIO_STATE_FALLING_ASLEEP); - falling_asleep_init(); + // The order of calls in the following blocks is inverted to avoid RAAL races. + if (timeslot_is_granted()) + { + state_set(RADIO_STATE_FALLING_ASLEEP); + falling_asleep_init(); + } + else + { + sleep_init(); + state_set(RADIO_STATE_SLEEP); + } } } nrf_802154_critical_section_exit(); } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } @@ -2946,6 +2403,8 @@ bool nrf_802154_core_receive(nrf_802154_term_t term_lvl, nrf_802154_notification_func_t notify_function, bool notify_abort) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result = nrf_802154_critical_section_enter(); if (result) @@ -2958,8 +2417,10 @@ bool nrf_802154_core_receive(nrf_802154_term_t term_lvl, if (result) { + m_trx_receive_frame_notifications_mask = + make_trx_frame_receive_notification_mask(); state_set(RADIO_STATE_RX); - rx_init(true); + rx_init(); } } else @@ -2983,6 +2444,8 @@ bool nrf_802154_core_receive(nrf_802154_term_t term_lvl, } } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } @@ -2993,29 +2456,42 @@ bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl, bool immediate, nrf_802154_notification_func_t notify_function) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) { - result = current_operation_terminate(term_lvl, req_orig, true); - - if (result) + /* Short-circuit evaluation in place. */ + if ((immediate) || (nrf_802154_core_hooks_pre_transmission(p_data, cca))) { - // Set state to RX in case sleep terminate succeeded, but transmit_begin fails. - state_set(RADIO_STATE_RX); - - mp_tx_data = p_data; - result = tx_init(p_data, cca, true); + result = current_operation_terminate(term_lvl, req_orig, true); - if (!immediate) + if (result) { - result = true; - } - } + m_coex_tx_request_mode = nrf_802154_pib_coex_tx_request_mode_get(); + m_trx_transmit_frame_notifications_mask = + make_trx_frame_transmit_notification_mask(cca); + m_flags.tx_diminished_prio = + m_coex_tx_request_mode == NRF_802154_COEX_TX_REQUEST_MODE_CCA_DONE; - if (result) - { - state_set(cca ? RADIO_STATE_CCA_TX : RADIO_STATE_TX); + state_set(cca ? RADIO_STATE_CCA_TX : RADIO_STATE_TX); + mp_tx_data = p_data; + + result = tx_init(p_data, cca); + if (immediate) + { + if (!result) + { + state_set(RADIO_STATE_RX); + rx_init(); + } + } + else + { + result = true; + } + } } if (notify_function != NULL) @@ -3033,11 +2509,15 @@ bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl, } } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } bool nrf_802154_core_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_us) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) @@ -3046,20 +2526,30 @@ bool nrf_802154_core_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_ if (result) { - state_set(RADIO_STATE_ED); + if (time_us < ED_ITER_DURATION) + { + time_us = ED_ITER_DURATION; + } + m_ed_time_left = time_us; m_ed_result = 0; - ed_init(true); + + state_set(RADIO_STATE_ED); + ed_init(); } nrf_802154_critical_section_exit(); } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } bool nrf_802154_core_cca(nrf_802154_term_t term_lvl) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) @@ -3069,17 +2559,21 @@ bool nrf_802154_core_cca(nrf_802154_term_t term_lvl) if (result) { state_set(RADIO_STATE_CCA); - cca_init(true); + cca_init(); } nrf_802154_critical_section_exit(); } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } bool nrf_802154_core_continuous_carrier(nrf_802154_term_t term_lvl) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) @@ -3089,79 +2583,82 @@ bool nrf_802154_core_continuous_carrier(nrf_802154_term_t term_lvl) if (result) { state_set(RADIO_STATE_CONTINUOUS_CARRIER); - continuous_carrier_init(true); + continuous_carrier_init(); } nrf_802154_critical_section_exit(); } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } -bool nrf_802154_core_notify_buffer_free(uint8_t * p_data) +bool nrf_802154_core_modulated_carrier(nrf_802154_term_t term_lvl, + const uint8_t * p_data) { - rx_buffer_t * p_buffer = (rx_buffer_t *)p_data; - bool in_crit_sect = critical_section_enter_and_verify_timeslot_length(); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - p_buffer->free = true; + bool result = critical_section_enter_and_verify_timeslot_length(); - if (in_crit_sect) + if (result) { - if (timeslot_is_granted()) - { - switch (m_state) - { - case RADIO_STATE_RX: - if (nrf_radio_state_get() == NRF_RADIO_STATE_RXIDLE) - { - assert(nrf_radio_shorts_get() == SHORTS_RX); - - rx_buffer_in_use_set(p_buffer); - - nrf_radio_packetptr_set(rx_buffer_get()); - nrf_radio_shorts_set(SHORTS_RX | SHORTS_RX_FREE_BUFFER); + result = current_operation_terminate(term_lvl, REQ_ORIG_CORE, true); - nrf_radio_task_trigger(NRF_RADIO_TASK_START); - } + if (result) + { + state_set(RADIO_STATE_MODULATED_CARRIER); + mp_tx_data = p_data; + modulated_carrier_init(p_data); + } - break; + nrf_802154_critical_section_exit(); + } - case RADIO_STATE_RX_ACK: - if (nrf_radio_state_get() == NRF_RADIO_STATE_RXIDLE) - { - assert(nrf_radio_shorts_get() == SHORTS_RX_ACK); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); - rx_buffer_in_use_set(p_buffer); + return result; +} - nrf_radio_packetptr_set(rx_buffer_get()); - nrf_radio_shorts_set(SHORTS_RX_ACK | SHORTS_RX_FREE_BUFFER); +bool nrf_802154_core_notify_buffer_free(uint8_t * p_data) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); - nrf_radio_task_trigger(NRF_RADIO_TASK_START); - } + rx_buffer_t * p_buffer = (rx_buffer_t *)p_data; + bool in_crit_sect = critical_section_enter_and_verify_timeslot_length(); - break; + p_buffer->free = true; - default: - // Don't perform any action in any other state (receiver should not be started). - break; + if (in_crit_sect) + { + if (timeslot_is_granted()) + { + if (nrf_802154_trx_receive_is_buffer_missing()) + { + rx_buffer_in_use_set(p_buffer); + nrf_802154_trx_receive_buffer_set(rx_buffer_get()); } } nrf_802154_critical_section_exit(); } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return true; } bool nrf_802154_core_channel_update(void) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) { if (timeslot_is_granted()) { - channel_set(nrf_802154_pib_channel_get()); + nrf_802154_trx_channel_set(nrf_802154_pib_channel_get()); } switch (m_state) @@ -3169,17 +2666,22 @@ bool nrf_802154_core_channel_update(void) case RADIO_STATE_RX: if (current_operation_terminate(NRF_802154_TERM_NONE, REQ_ORIG_CORE, true)) { - rx_init(true); + rx_init(); } - break; case RADIO_STATE_CONTINUOUS_CARRIER: if (timeslot_is_granted()) { - nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE); + nrf_802154_trx_continuous_carrier_restart(); } + break; + case RADIO_STATE_MODULATED_CARRIER: + if (timeslot_is_granted()) + { + nrf_802154_trx_modulated_carrier_restart(); + } break; default: @@ -3190,35 +2692,43 @@ bool nrf_802154_core_channel_update(void) nrf_802154_critical_section_exit(); } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } bool nrf_802154_core_cca_cfg_update(void) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) { if (timeslot_is_granted()) { - cca_configuration_update(); + nrf_802154_trx_cca_configuration_update(); } nrf_802154_critical_section_exit(); } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } bool nrf_802154_core_rssi_measure(void) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result = critical_section_enter_and_verify_timeslot_length(); if (result) { if (timeslot_is_granted() && (m_state == RADIO_STATE_RX)) { - rssi_measure(); + result = nrf_802154_trx_rssi_measure(); } else { @@ -3228,14 +2738,18 @@ bool nrf_802154_core_rssi_measure(void) nrf_802154_critical_section_exit(); } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } bool nrf_802154_core_last_rssi_measurement_get(int8_t * p_rssi) { + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + bool result = false; - bool rssi_started = m_flags.rssi_started; bool in_crit_sect = false; + bool rssi_started = nrf_802154_trx_rssi_measure_is_started(); if (rssi_started) { @@ -3247,9 +2761,13 @@ bool nrf_802154_core_last_rssi_measurement_get(int8_t * p_rssi) // Checking if a timeslot is granted is valid only in a critical section if (timeslot_is_granted()) { - rssi_measurement_wait(); - *p_rssi = rssi_last_measurement_get(); - result = true; + rssi_started = nrf_802154_trx_rssi_measure_is_started(); + if (rssi_started) + { + rssi_measurement_wait(); + *p_rssi = rssi_last_measurement_get(); + result = true; + } } } @@ -3258,14 +2776,64 @@ bool nrf_802154_core_last_rssi_measurement_get(int8_t * p_rssi) nrf_802154_critical_section_exit(); } + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + + return result; +} + +bool nrf_802154_core_antenna_update(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + bool result = critical_section_enter_and_verify_timeslot_length(); + + if (result) + { + if (timeslot_is_granted()) + { + nrf_802154_trx_antenna_update(); + } + + nrf_802154_critical_section_exit(); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; } -#if NRF_802154_INTERNAL_RADIO_IRQ_HANDLING -void RADIO_IRQHandler(void) -#else // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING -void nrf_802154_core_irq_handler(void) -#endif // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING +int8_t nrf_802154_sl_ant_div_rssi_measure_get(void) { - irq_handler(); + int8_t result = NRF_802154_RSSI_INVALID; + + // This function is supposed to be called after detecting frame prestarted event, but before + // detecting valid frame address. This means that we're currently in critical section, but the + // timeslot is not yet extended due to detecting valid frame. To avoid invalid timeslot extension + // due to blocking rssi measurements, antenna check can be aborted here if timeslot is about to end. + // Antenna switching takes 200 ns (250 ns with safety margin), while rssi measurement - 250, + // which gives total time of 750 ns. + // 750 ns is less than safety margin, so timeslot us left different than 0 is sufficient. + if (!nrf_802154_rsch_timeslot_us_left_get()) + { + return result; + } + + nrf_802154_trx_rssi_measure(); + + if (nrf_802154_trx_rssi_measure_is_started()) + { + while (!nrf_802154_trx_rssi_sample_is_available()) + { + // Intentionally empty: This function is called from a critical section. + // WFE would not be waken up by a RADIO event. + } + + uint8_t rssi_sample = nrf_802154_trx_rssi_last_sample_get(); + + rssi_sample = nrf_802154_rssi_sample_corrected_get(rssi_sample); + + result = -((int8_t)rssi_sample); + } + + return result; } diff --git a/src/nrf_802154_core.h b/src/nrf_802154_core.h index 381a038..59dbe9c 100644 --- a/src/nrf_802154_core.h +++ b/src/nrf_802154_core.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -74,6 +75,9 @@ typedef enum // Continuous carrier RADIO_STATE_CONTINUOUS_CARRIER, ///< Emitting the continuous carrier wave. + + // Modulated carrier + RADIO_STATE_MODULATED_CARRIER ///< Emitting the modulated carrier signal. } radio_state_t; /** @@ -163,6 +167,8 @@ bool nrf_802154_core_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_ /** * @brief Requests the transition to the @ref RADIO_STATE_CCA state. * + * When the CCA procedure is finished, the driver transitions to the @ref RADIO_STATE_RX state. + * * @param[in] term_lvl Termination level of this request. Selects procedures to abort. * * @retval true Entering the CCA state succeeded. @@ -173,8 +179,6 @@ bool nrf_802154_core_cca(nrf_802154_term_t term_lvl); /** * @brief Requests the transition to the @ref RADIO_STATE_CONTINUOUS_CARRIER state. * - * When the CCA procedure is finished, the driver transitions to the @ref RADIO_STATE_RX state. - * * @param[in] term_lvl Termination level of this request. Selects procedures to abort. * * @retval true Entering the continuous carrier state succeeded. @@ -183,6 +187,19 @@ bool nrf_802154_core_cca(nrf_802154_term_t term_lvl); */ bool nrf_802154_core_continuous_carrier(nrf_802154_term_t term_lvl); +/** + * @brief Requests the transition to the @ref RADIO_STATE_MODULATED_CARRIER state. + * + * @param[in] term_lvl Termination level of this request. Selects procedures to abort. + * @param[in] p_data Data buffer to modulate the carrier with. + * + * @retval true Entering the modulated carrier state succeeded. + * @retval false Entering the modulated carrier state failed + * (the driver is performing other procedure). + */ +bool nrf_802154_core_modulated_carrier(nrf_802154_term_t term_lvl, + const uint8_t * p_data); + /*************************************************************************************************** * @section State machine notifications **************************************************************************************************/ @@ -202,9 +219,9 @@ bool nrf_802154_core_notify_buffer_free(uint8_t * p_data); * @brief Notifies the core module that the next higher layer requested the change of the channel. * * The core is expected to update the frequency register of the peripheral and, if it is - * in the @ref RADIO_STATE_RX or in the @ref RADIO_STATE_CONTINUOUS_CARRIER state, the transceiver - * is disabled and enabled again to use the new channel. - * + * in the @ref RADIO_STATE_RX, in the @ref RADIO_STATE_CONTINUOUS_CARRIER + * or in the @ref RADIO_STATE_MODULATED_CARRIER state, the transceiver is disabled + * and enabled again to use the new channel. */ bool nrf_802154_core_channel_update(void); @@ -226,6 +243,11 @@ bool nrf_802154_core_rssi_measure(void); */ bool nrf_802154_core_last_rssi_measurement_get(int8_t * p_rssi); +/** + * @brief Notifies the core module that the next higher layer requested the change of the antenna. + */ +bool nrf_802154_core_antenna_update(void); + #if !NRF_802154_INTERNAL_IRQ_HANDLING /** * @brief Notifies the core module that there is a pending IRQ to be handled. diff --git a/src/nrf_802154_core_hooks.c b/src/nrf_802154_core_hooks.c index 7035b68..e5d3ba4 100644 --- a/src/nrf_802154_core_hooks.c +++ b/src/nrf_802154_core_hooks.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -44,10 +45,12 @@ #include "mac_features/nrf_802154_ack_timeout.h" #include "mac_features/nrf_802154_csma_ca.h" #include "mac_features/nrf_802154_delayed_trx.h" +#include "mac_features/nrf_802154_ifs.h" #include "nrf_802154_config.h" #include "nrf_802154_types.h" typedef bool (* abort_hook)(nrf_802154_term_t term_lvl, req_originator_t req_orig); +typedef bool (* pre_transmission_hook)(const uint8_t * p_frame, bool cca); typedef void (* transmitted_hook)(const uint8_t * p_frame); typedef bool (* tx_failed_hook)(const uint8_t * p_frame, nrf_802154_tx_error_t error); typedef bool (* tx_started_hook)(const uint8_t * p_frame); @@ -73,6 +76,18 @@ static const abort_hook m_abort_hooks[] = nrf_802154_delayed_trx_abort, #endif +#if NRF_802154_IFS_ENABLED + nrf_802154_ifs_abort, +#endif + + NULL, +}; + +static const pre_transmission_hook m_pre_transmission_hooks[] = +{ +#if NRF_802154_IFS_ENABLED + nrf_802154_ifs_pretransmission, +#endif NULL, }; @@ -81,7 +96,9 @@ static const transmitted_hook m_transmitted_hooks[] = #if NRF_802154_ACK_TIMEOUT_ENABLED nrf_802154_ack_timeout_transmitted_hook, #endif - +#if NRF_802154_IFS_ENABLED + nrf_802154_ifs_transmitted_hook, +#endif NULL, }; @@ -151,6 +168,29 @@ bool nrf_802154_core_hooks_terminate(nrf_802154_term_t term_lvl, req_originator_ return result; } +bool nrf_802154_core_hooks_pre_transmission(const uint8_t * p_frame, bool cca) +{ + bool result = true; + + for (uint32_t i = 0; i < sizeof(m_pre_transmission_hooks) / sizeof(m_pre_transmission_hooks[0]); + i++) + { + if (m_pre_transmission_hooks[i] == NULL) + { + break; + } + + result = m_pre_transmission_hooks[i](p_frame, cca); + + if (!result) + { + break; + } + } + + return result; +} + void nrf_802154_core_hooks_transmitted(const uint8_t * p_frame) { for (uint32_t i = 0; i < sizeof(m_transmitted_hooks) / sizeof(m_transmitted_hooks[0]); i++) diff --git a/src/nrf_802154_core_hooks.h b/src/nrf_802154_core_hooks.h index 41e0dd2..283d20c 100644 --- a/src/nrf_802154_core_hooks.h +++ b/src/nrf_802154_core_hooks.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_CORE_HOOKS_H__ @@ -58,6 +59,19 @@ */ bool nrf_802154_core_hooks_terminate(nrf_802154_term_t term_lvl, req_originator_t req_orig); +/** + * @brief Processes hooks which are to fire before the transmission request. + * + * @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame + * that is to be transmitted. + * + * @param[in] cca Whether to start with cca or not. + * + * @retval true Frame can be sent immediately. + * @retval false Hooks have handled the frame - upper layer should not worry about it anymore. + */ +bool nrf_802154_core_hooks_pre_transmission(const uint8_t * p_frame, bool cca); + /** * @brief Processes hooks for the transmitted event. * diff --git a/src/nrf_802154_critical_section.c b/src/nrf_802154_critical_section.c index 227253d..584a428 100644 --- a/src/nrf_802154_critical_section.c +++ b/src/nrf_802154_critical_section.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -34,6 +35,8 @@ * */ +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_CRITICAL_SECTION + #include "nrf_802154_critical_section.h" #include @@ -41,7 +44,8 @@ #include "nrf_802154_config.h" #include "nrf_802154_debug.h" -#include "nrf_radio.h" +#include "nrf_802154_utils.h" +#include "hal/nrf_radio.h" #include "rsch/nrf_802154_rsch.h" #include "platform/lp_timer/nrf_802154_lp_timer.h" #include "platform/irq/nrf_802154_irq.h" @@ -117,6 +121,10 @@ static bool critical_section_enter(bool forced) (m_nested_critical_section_counter == 0) || nested_critical_section_is_allowed_in_this_context()) { + nrf_802154_mcu_critical_state_t mcu_cs; + + nrf_802154_mcu_critical_enter(mcu_cs); + do { cnt = __LDREXB(&m_nested_critical_section_counter); @@ -129,6 +137,8 @@ static bool critical_section_enter(bool forced) nrf_802154_lp_timer_critical_section_enter(); radio_critical_section_enter(); + nrf_802154_mcu_critical_exit(mcu_cs); + m_critical_section_monitor++; result = true; @@ -209,11 +219,11 @@ bool nrf_802154_critical_section_enter(void) { bool result; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CRIT_SECT_ENTER); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); result = critical_section_enter(false); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CRIT_SECT_ENTER); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } @@ -222,22 +232,22 @@ void nrf_802154_critical_section_forcefully_enter(void) { bool critical_section_entered; - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CRIT_SECT_ENTER); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); critical_section_entered = critical_section_enter(true); assert(critical_section_entered); (void)critical_section_entered; - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CRIT_SECT_ENTER); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } void nrf_802154_critical_section_exit(void) { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_CRIT_SECT_EXIT); + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); critical_section_exit(); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_CRIT_SECT_EXIT); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); } void nrf_802154_critical_section_nesting_allow(void) diff --git a/src/nrf_802154_critical_section.h b/src/nrf_802154_critical_section.h index 5237a46..607fe8f 100644 --- a/src/nrf_802154_critical_section.h +++ b/src/nrf_802154_critical_section.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_CRITICAL_SECTION_H__ diff --git a/src/nrf_802154_debug.c b/src/nrf_802154_debug.c index 9e4f579..7d5c09c 100644 --- a/src/nrf_802154_debug.c +++ b/src/nrf_802154_debug.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -38,132 +39,37 @@ #include -#include "nrf.h" -#include "nrf_gpio.h" -#include "nrf_gpiote.h" -#include "nrf_ppi.h" +#include "nrf_802154_debug_log_codes.h" -#if ENABLE_DEBUG_LOG -/// Buffer used to store debug log messages. -volatile uint32_t nrf_802154_debug_log_buffer[NRF_802154_DEBUG_LOG_BUFFER_LEN]; -/// Index of the log buffer pointing to the element that should be filled with next log message. -volatile uint32_t nrf_802154_debug_log_ptr = 0; +void nrf_802154_debug_gpio_init(void); +void nrf_802154_debug_assert_init(void); -#endif - -#if ENABLE_DEBUG_GPIO -/** - * @brief Initialize PPI to toggle GPIO pins on radio events. - */ -static void radio_event_gpio_toggle_init(void) +void nrf_802154_debug_init(void) { - nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_END); - nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_DISABLED); - nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_READY); - nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_FRAMESTART); - nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_EDEND); - - nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_END, - PIN_DBG_RADIO_EVT_END, - NRF_GPIOTE_POLARITY_TOGGLE, - NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_DISABLED, - PIN_DBG_RADIO_EVT_DISABLED, - NRF_GPIOTE_POLARITY_TOGGLE, - NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_READY, - PIN_DBG_RADIO_EVT_READY, - NRF_GPIOTE_POLARITY_TOGGLE, - NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_FRAMESTART, - PIN_DBG_RADIO_EVT_FRAMESTART, - NRF_GPIOTE_POLARITY_TOGGLE, - NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_EDEND, - PIN_DBG_RADIO_EVT_EDEND, - NRF_GPIOTE_POLARITY_TOGGLE, - NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_END); - nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_DISABLED); - nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_READY); - nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_FRAMESTART); - nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_EDEND); +#if NRF_802154_SL_ENABLE_DEBUG_LOG + // dummy_local is needed for only one purpose - to ensure the presence of typedef-s + // (used inside nrf_802154_drv_typedefs_to_save_in_elf_t union) in final .elf file. + // The original reason is that the information about particular 'typdef' is included + // in the .elf file only if this 'typdef' is used for the actual operation in the code. + nrf_802154_drv_typedefs_to_save_in_elf_t volatile dummy_local; - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_END, - (uint32_t)&NRF_RADIO->EVENTS_END, - nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_0)); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_DISABLED, - (uint32_t)&NRF_RADIO->EVENTS_DISABLED, - nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_1)); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_READY, - (uint32_t)&NRF_RADIO->EVENTS_READY, - nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_2)); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_FRAMESTART, - (uint32_t)&NRF_RADIO->EVENTS_FRAMESTART, - nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_3)); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_EDEND, - (uint32_t)&NRF_RADIO->EVENTS_EDEND, - nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_4)); - - nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_END); - nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_DISABLED); - nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_READY); - nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_FRAMESTART); - nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_EDEND); -} - -/** - * @brief Initialize GPIO to set it simulated arbiter events. - */ -static void raal_simulator_gpio_init(void) -{ -#if RAAL_SIMULATOR - nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_ACTIVE); - nrf_gpio_cfg_output(PIN_DBG_RAAL_CRITICAL_SECTION); + dummy_local.dummy00tag = 0; + (void)dummy_local; #endif -} - -#endif // ENABLE_DEBUG_GPIO -void nrf_802154_debug_init(void) -{ #if ENABLE_DEBUG_GPIO - radio_event_gpio_toggle_init(); - raal_simulator_gpio_init(); + nrf_802154_debug_gpio_init(); #endif // ENABLE_DEBUG_GPIO -} -#if ENABLE_DEBUG_ASSERT -void __assert_func(const char * file, int line, const char * func, const char * cond) -{ - (void)file; - (void)line; - (void)func; - (void)cond; - -#if defined(ENABLE_DEBUG_ASSERT_BKPT) && (ENABLE_DEBUG_ASSERT_BKPT != 0) - __BKPT(0); -#endif - __disable_irq(); - - while (1) - ; -} - -void __aeabi_assert(const char * expr, const char * file, int line) -{ - (void)expr; - (void)file; - (void)line; - -#if defined(ENABLE_DEBUG_ASSERT_BKPT) && (ENABLE_DEBUG_ASSERT_BKPT != 0) - __BKPT(0); -#endif - __disable_irq(); +#if ENABLE_DEBUG_LOG +#warning attempt to use deprecated ENABLE_DEBUG_LOG switch +// When linking with SL use NRF_802154_SL_ENABLE_DEBUG_LOG instead +#endif // ENABLE_DEBUG_LOG - while (1) - ; -} + nrf_802154_sl_log_init(); +#if ENABLE_DEBUG_ASSERT + nrf_802154_debug_assert_init(); #endif // ENABLE_DEBUG_ASSERT +} diff --git a/src/nrf_802154_debug.h b/src/nrf_802154_debug.h index c2b8226..534abc0 100644 --- a/src/nrf_802154_debug.h +++ b/src/nrf_802154_debug.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -38,104 +39,32 @@ #include +#include "nrf_802154_config.h" +#include "nrf_802154_sl_log.h" +#include "nrf_802154_debug_log.h" #include "nrf_802154_debug_core.h" #ifdef __cplusplus extern "C" { #endif -#define EVENT_SET_STATE 0x0005UL -#define EVENT_RADIO_RESET 0x0006UL - -#define FUNCTION_SLEEP 0x0001UL -#define FUNCTION_RECEIVE 0x0002UL -#define FUNCTION_TRANSMIT 0x0003UL -#define FUNCTION_ENERGY_DETECTION 0x0004UL -#define FUNCTION_BUFFER_FREE 0x0005UL -#define FUNCTION_CCA 0x0006UL -#define FUNCTION_CONTINUOUS_CARRIER 0x0007UL -#define FUNCTION_CSMACA 0x0008UL -#define FUNCTION_TRANSMIT_AT 0x0009UL -#define FUNCTION_RECEIVE_AT 0x000AUL -#define FUNCTION_TRANSMIT_AT_CANCEL 0x000BUL -#define FUNCTION_RECEIVE_AT_CANCEL 0x000CUL - -#define FUNCTION_IRQ_HANDLER 0x0100UL -#define FUNCTION_EVENT_FRAMESTART 0x0101UL -#define FUNCTION_EVENT_BCMATCH 0x0102UL -#define FUNCTION_EVENT_END 0x0103UL -#define FUNCTION_EVENT_DISABLED 0x0104UL -#define FUNCTION_EVENT_READY 0x0105UL -#define FUNCTION_EVENT_CCAIDLE 0x0106UL -#define FUNCTION_EVENT_CCABUSY 0x0107UL -#define FUNCTION_EVENT_EDEND 0x0108UL -#define FUNCTION_EVENT_PHYEND 0x0109UL -#define FUNCTION_EVENT_CRCOK 0x010AUL -#define FUNCTION_EVENT_CRCERROR 0x010BUL - -#define FUNCTION_AUTO_ACK_ABORT 0x0201UL -#define FUNCTION_TIMESLOT_STARTED 0x0202UL -#define FUNCTION_TIMESLOT_ENDED 0x0203UL -#define FUNCTION_CRIT_SECT_ENTER 0x0204UL -#define FUNCTION_CRIT_SECT_EXIT 0x0205UL - -/* Reserved for RAAL: 0x0300 - 0x047F */ - -#define FUNCTION_RSCH_CONTINUOUS_ENTER 0x0480UL -#define FUNCTION_RSCH_CONTINUOUS_EXIT 0x0481UL -#define FUNCTION_RSCH_CRITICAL_SECTION_ENTER 0x0482UL -#define FUNCTION_RSCH_CRITICAL_SECTION_EXIT 0x0483UL -#define FUNCTION_RSCH_TIMESLOT_STARTED 0x0484UL -#define FUNCTION_RSCH_TIMESLOT_ENDED 0x0485UL -#define FUNCTION_RSCH_DELAYED_TIMESLOT_REQ 0x048BUL -#define FUNCTION_RSCH_TIMER_DELAYED_PREC 0x048CUL -#define FUNCTION_RSCH_TIMER_DELAYED_START 0x048DUL -#define FUNCTION_RSCH_DELAYED_TIMESLOT_CANCEL 0x048EUL - -#define FUNCTION_CSMA_ABORT 0x0500UL -#define FUNCTION_CSMA_TX_FAILED 0x0501UL -#define FUNCTION_CSMA_TX_STARTED 0x0502UL -#define FUNCTION_CSMA_CHANNEL_BUSY 0x0503UL -#define FUNCTION_CSMA_FRAME_TRANSMIT 0x0504UL - -#define FUNCTION_TSCH_ADD 0x0600UL -#define FUNCTION_TSCH_FIRED 0x0601UL - -#define FUNCTION_TCOOR_START 0x0700UL -#define FUNCTION_TCOOR_STOP 0x0701UL -#define FUNCTION_TCOOR_TIMESTAMP_PREPARE 0x0702UL -#define FUNCTION_TCOOR_TIMESTAMP_GET 0x0703UL -#define FUNCTION_TCOOR_SYNCHRONIZED 0x0704UL - -#define FUNCTION_DTRX_RX_TIMEOUT 0x0800UL - -#define FUNCTION_ACK_TIMEOUT_FIRED 0x0900UL - -#define FUNCTION_mutex_trylock 0x1000UL -#define FUNCTION_mutex_unlock 0x1001UL -#define FUNCTION_max_prio_for_delayed_timeslot_get 0x1002UL -#define FUNCTION_required_prio_lvl_get 0x1003UL -#define FUNCTION_prec_approved_prio_set 0x1004UL -#define FUNCTION_all_prec_update 0x1005UL -#define FUNCTION_approved_prio_lvl_get 0x1006UL -#define FUNCTION_requested_prio_lvl_is_at_least 0x1007UL -#define FUNCTION_notify_core 0x1008UL - #ifdef NRF52811_XXAA #define PIN_DBG_RADIO_EVT_END 13 #define PIN_DBG_RADIO_EVT_DISABLED 14 -#define PIN_DBG_RADIO_EVT_READY 21 +#define PIN_DBG_RADIO_EVT_READY 17 #define PIN_DBG_RADIO_EVT_FRAMESTART 18 #define PIN_DBG_RADIO_EVT_EDEND 25 +#define PIN_DBG_RADIO_EVT_PHYEND 24 #else #define PIN_DBG_RADIO_EVT_END 11 #define PIN_DBG_RADIO_EVT_DISABLED 12 -#define PIN_DBG_RADIO_EVT_READY 18 +#define PIN_DBG_RADIO_EVT_READY 13 #define PIN_DBG_RADIO_EVT_FRAMESTART 14 #define PIN_DBG_RADIO_EVT_EDEND 25 +#define PIN_DBG_RADIO_EVT_PHYEND 24 #endif @@ -144,12 +73,14 @@ extern "C" { #define PPI_DBG_RADIO_EVT_READY 2 #define PPI_DBG_RADIO_EVT_FRAMESTART 3 #define PPI_DBG_RADIO_EVT_EDEND 4 +#define PPI_DBG_RADIO_EVT_PHYEND 5 #define GPIOTE_DBG_RADIO_EVT_END 0 #define GPIOTE_DBG_RADIO_EVT_DISABLED 1 #define GPIOTE_DBG_RADIO_EVT_READY 2 #define GPIOTE_DBG_RADIO_EVT_FRAMESTART 3 #define GPIOTE_DBG_RADIO_EVT_EDEND 4 +#define GPIOTE_DBG_RADIO_EVT_PHYEND 5 #if ENABLE_DEBUG_GPIO @@ -157,19 +88,22 @@ extern "C" { (1 << PIN_DBG_RADIO_EVT_DISABLED) | \ (1 << PIN_DBG_RADIO_EVT_READY) | \ (1 << PIN_DBG_RADIO_EVT_FRAMESTART) | \ - (1 << PIN_DBG_RADIO_EVT_EDEND)) + (1 << PIN_DBG_RADIO_EVT_EDEND) | \ + (1 << PIN_DBG_RADIO_EVT_PHYEND)) #define NRF_802154_DEBUG_PPI_CHANNELS_USED_MASK ((1 << PPI_DBG_RADIO_EVT_END) | \ (1 << PPI_DBG_RADIO_EVT_DISABLED) | \ (1 << PPI_DBG_RADIO_EVT_READY) | \ (1 << PPI_DBG_RADIO_EVT_FRAMESTART) | \ - (1 << PPI_DBG_RADIO_EVT_EDEND)) + (1 << PPI_DBG_RADIO_EVT_EDEND) | \ + (1 << PPI_DBG_RADIO_EVT_PHYEND)) #define NRF_802154_DEBUG_GPIOTE_CHANNELS_USED_MASK ((1 << GPIOTE_DBG_RADIO_EVT_END) | \ (1 << GPIOTE_DBG_RADIO_EVT_DISABLED) | \ (1 << GPIOTE_DBG_RADIO_EVT_READY) | \ (1 << GPIOTE_DBG_RADIO_EVT_FRAMESTART) | \ - (1 << GPIOTE_DBG_RADIO_EVT_EDEND)) + (1 << GPIOTE_DBG_RADIO_EVT_EDEND) | \ + (1 << GPIOTE_DBG_RADIO_EVT_PHYEND)) #else // ENABLE_DEBUG_GPIO @@ -179,6 +113,11 @@ extern "C" { #endif // ENABLE_DEBUG_GPIO +/** + * @brief Initializes debug helpers for the nRF 802.15.4 driver. + */ +void nrf_802154_debug_init(void); + #ifdef __cplusplus } #endif diff --git a/src/nrf_802154_debug_assert.c b/src/nrf_802154_debug_assert.c new file mode 100644 index 0000000..2abbb48 --- /dev/null +++ b/src/nrf_802154_debug_assert.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements debug assert helpers for the nRF 802.15.4 radio driver. + * + */ + +#include "nrf_802154_debug.h" + +#include + +#include "nrf.h" + +void __assert_func(const char * file, int line, const char * func, const char * cond) +{ + (void)file; + (void)line; + (void)func; + (void)cond; + +#if defined(ENABLE_DEBUG_ASSERT_BKPT) && (ENABLE_DEBUG_ASSERT_BKPT != 0) + __BKPT(0); +#endif + __disable_irq(); + + while (1) + ; +} + +void __aeabi_assert(const char * expr, const char * file, int line) +{ + (void)expr; + (void)file; + (void)line; + +#if defined(ENABLE_DEBUG_ASSERT_BKPT) && (ENABLE_DEBUG_ASSERT_BKPT != 0) + __BKPT(0); +#endif + __disable_irq(); + + while (1) + ; +} + +void nrf_802154_debug_assert_init(void) +{ + // Intentionally empty +} diff --git a/src/nrf_802154_debug_core.h b/src/nrf_802154_debug_core.h index 8da136c..dfc4cb4 100644 --- a/src/nrf_802154_debug_core.h +++ b/src/nrf_802154_debug_core.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -42,20 +43,15 @@ extern "C" { #endif -#define NRF_802154_DEBUG_LOG_BUFFER_LEN 1024 - -#define EVENT_TRACE_ENTER 0x0001UL -#define EVENT_TRACE_EXIT 0x0002UL - -#define PIN_DBG_TIMESLOT_ACTIVE 3 -#define PIN_DBG_TIMESLOT_EXTEND_REQ 4 -#define PIN_DBG_TIMESLOT_SESSION_IDLE 16 -#define PIN_DBG_TIMESLOT_RADIO_IRQ 28 -#define PIN_DBG_TIMESLOT_FAILED 29 -#define PIN_DBG_TIMESLOT_BLOCKED 30 -#define PIN_DBG_RAAL_CRITICAL_SECTION 15 +#define PIN_DBG_TIMESLOT_ACTIVE 3 +#define PIN_DBG_TIMESLOT_EXTEND_REQ 4 +#define PIN_DBG_TIMESLOT_SESSION_IDLE 16 +#define PIN_DBG_TIMESLOT_RADIO_IRQ 28 +#define PIN_DBG_TIMESLOT_FAILED 29 +#define PIN_DBG_TIMESLOT_BLOCKED 30 +#define PIN_DBG_RAAL_CRITICAL_SECTION 15 -#define PIN_DBG_RTC0_EVT_REM 31 +#define PIN_DBG_RTC0_EVT_REM 31 #if ENABLE_DEBUG_GPIO @@ -73,59 +69,6 @@ extern "C" { #endif -#ifndef DEBUG_VERBOSITY -#define DEBUG_VERBOSITY 1 -#endif - -#ifndef CU_TEST -#if ENABLE_DEBUG_LOG -extern volatile uint32_t nrf_802154_debug_log_buffer[ - NRF_802154_DEBUG_LOG_BUFFER_LEN]; -extern volatile uint32_t nrf_802154_debug_log_ptr; - -#define nrf_802154_log(EVENT_CODE, EVENT_ARG) \ - do \ - { \ - uint32_t ptr = nrf_802154_debug_log_ptr; \ - \ - nrf_802154_debug_log_buffer[ptr] = ((EVENT_CODE) | ((EVENT_ARG) << 16)); \ - nrf_802154_debug_log_ptr = \ - ptr < (NRF_802154_DEBUG_LOG_BUFFER_LEN - 1) ? ptr + 1 : 0; \ - } \ - while (0) - -#else // ENABLE_DEBUG_LOG - -#define nrf_802154_log(EVENT_CODE, EVENT_ARG) (void)(EVENT_ARG) - -#endif // ENABLE_DEBUG_LOG - -#define nrf_802154_log_entry(function, verbosity) \ - do \ - { \ - if (verbosity <= DEBUG_VERBOSITY) \ - { \ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_ ## function); \ - } \ - } \ - while (0) - -#define nrf_802154_log_exit(function, verbosity) \ - do \ - { \ - if (verbosity <= DEBUG_VERBOSITY) \ - { \ - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_ ## function); \ - } \ - } \ - while (0) - -#else // CU_TEST - -#define nrf_802154_log(EVENT_CODE, EVENT_ARG) - -#endif - #if ENABLE_DEBUG_GPIO #define nrf_802154_pin_set(pin) NRF_P0->OUTSET = (1UL << (pin)) @@ -148,11 +91,6 @@ extern volatile uint32_t nrf_802154_debug_log_ptr; #endif // ENABLE_DEBUG_GPIO -/** - * @brief Initializes debug helpers for the nRF 802.15.4 driver. - */ -void nrf_802154_debug_init(void); - #ifdef __cplusplus } #endif diff --git a/src/nrf_802154_debug_gpio.c b/src/nrf_802154_debug_gpio.c new file mode 100644 index 0000000..fbc4e4c --- /dev/null +++ b/src/nrf_802154_debug_gpio.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file implements debug helpers for the nRF 802.15.4 radio driver. + * + */ + +#include "nrf_802154_debug.h" + +#include + +#include "nrf.h" +#include "hal/nrf_gpio.h" +#include "hal/nrf_gpiote.h" +#include "hal/nrf_ppi.h" + +/** + * @brief Initialize PPI to toggle GPIO pins on radio events. + */ +static void radio_event_gpio_toggle_init(void) +{ + nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_END); + nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_DISABLED); + nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_READY); + + nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_END, + PIN_DBG_RADIO_EVT_END, + NRF_GPIOTE_POLARITY_TOGGLE, + NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_DISABLED, + PIN_DBG_RADIO_EVT_DISABLED, + NRF_GPIOTE_POLARITY_TOGGLE, + NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_READY, + PIN_DBG_RADIO_EVT_READY, + NRF_GPIOTE_POLARITY_TOGGLE, + NRF_GPIOTE_INITIAL_VALUE_HIGH); + + nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_END); + nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_DISABLED); + nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_READY); + + nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_END, + (uint32_t)&NRF_RADIO->EVENTS_END, + nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_0)); + nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_DISABLED, + (uint32_t)&NRF_RADIO->EVENTS_DISABLED, + nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_1)); + nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_READY, + (uint32_t)&NRF_RADIO->EVENTS_READY, + nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_2)); + + nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_END); + nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_DISABLED); + nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_READY); +} + +/** + * @brief Initialize GPIO to set it simulated arbiter events. + */ +static void raal_simulator_gpio_init(void) +{ +#if RAAL_SIMULATOR + nrf_gpio_cfg_output(PIN_DBG_TIMESLOT_ACTIVE); + nrf_gpio_cfg_output(PIN_DBG_RAAL_CRITICAL_SECTION); +#endif +} + +void nrf_802154_debug_gpio_init(void) +{ + radio_event_gpio_toggle_init(); + raal_simulator_gpio_init(); +} diff --git a/src/nrf_802154_debug_log.h b/src/nrf_802154_debug_log.h new file mode 100644 index 0000000..a816a7a --- /dev/null +++ b/src/nrf_802154_debug_log.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_802154_DEBUG_LOG_H_ +#define NRF_802154_DEBUG_LOG_H_ + +#include "nrf_802154_config.h" +#include "nrf_802154_sl_log.h" +#include "nrf_802154_debug_log_codes.h" + +/**@brief Records log about entry to a function. + * @param verbosity Verbosity level of the module in which log is recorded required to emit log. + */ +#define nrf_802154_log_function_enter(verbosity) \ + nrf_802154_sl_log_function_enter(verbosity) + +/**@brief Records log about exit from a function. + * @param verbosity Verbosity level of the module in which log is recorded required to emit log. + */ +#define nrf_802154_log_function_exit(verbosity) \ + nrf_802154_sl_log_function_exit(verbosity) + +/**@brief Records log about event (with parameter) related to current module. + * @param verbosity Verbosity level of the module in which log is recorded required to emit log. + * @param local_event_id Event identifier whose meaning is defined within scope of the module + * in which log is recorded. Possible values 0...63 + * @param param_u16 Additional parameter to be logged with event. Meaning + * of the parameter is defined by the module in which + * the log is recorded and event_id. + */ +#define nrf_802154_log_local_event(verbosity, local_event_id, param_u16) \ + nrf_802154_sl_log_local_event(verbosity, local_event_id, param_u16) + +/**@brief Records log about event (with parameter) related to global resource. + * @param verbosity Verbosity level of the module in which log is recorded required to emit log. + * @param event_id Event identifier whose meaning is defined globally. Possible values 0...63 + * @param param_u16 Additional parameter to be logged with event. Meaning + * of the parameter is defined by value of global_event_id. + */ +#define nrf_802154_log_global_event(verbosity, global_event_id, param_u16) \ + nrf_802154_sl_log_global_event(verbosity, global_event_id, param_u16) + +#endif /* NRF_802154_DEBUG_LOG_H_ */ diff --git a/src/nrf_802154_debug_log_codes.h b/src/nrf_802154_debug_log_codes.h new file mode 100644 index 0000000..918a612 --- /dev/null +++ b/src/nrf_802154_debug_log_codes.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_802154_DEBUG_LOG_CODES_H_ +#define NRF_802154_DEBUG_LOG_CODES_H_ + +#include "nrf_802154_sl_log.h" + +/** + * @brief List of C modules in nRF 802.15.4 Driver, with theirs ID-s + * + * Range of possible values for the 802.15.4 Driver modules has been indicated + * in nrf_802154_sl_log.h (see "Distribution of IDs for Debug Logs" in there) + * Prefix "NRF_802154_DRV_MODULE_ID_" is mandatory here, + * the final part is the module name to be presented by "event_decoder" tool. + * + * @note Certain NRF_802154_DRV_MODULE_ID.. value may be shared + * between alternative implementations of module + * (e.g. random_stdlib/random_zephyr/random_newlib) + * In other cases they must be unique. + * This enum must exist in .elf file to provide metadata for decoder.html tool + * (enum is extracted from .elf in the preparatory stage before using decoder.html) + */ +typedef enum +{ + NRF_802154_DRV_MODULE_ID_APPLICATION = 1U, + NRF_802154_DRV_MODULE_ID_CORE = 2U, + NRF_802154_DRV_MODULE_ID_CRITICAL_SECTION = 3U, + NRF_802154_DRV_MODULE_ID_TRX = 4U, + NRF_802154_DRV_MODULE_ID_CSMACA = 5U, + NRF_802154_DRV_MODULE_ID_DELAYED_TRX = 6U, + NRF_802154_DRV_MODULE_ID_ACK_TIMEOUT = 7U, + NRF_802154_DRV_MODULE_ID_TRX_PPI = 8U, +} nrf_802154_drv_modules_list_t; + +/** + * @brief List of LOCAL EVENTS generated by module CORE + * + * To define elements of this enum, use + * - syntax: NRF_802154_LOG_LOCAL_EVENT_ID_{m}__{e} = {nID} + * or + * - macro: NRF_802154_LOG_L_EVENT_DEFINE({m},{e},{nID},{p_values}) + * where: + * {m} is the name of module + * {e} is the name of local event + * {nID} is numeric ID of local event (unique in module {m}) + * {p_values} further enum that defines the set of possible values of parameter for event {e} + * + * Both options (syntax/macro) are equivalent, except that using the macro causes additional + * link creation to {p_values}. See below - currently in the module CORE there is an local + * event SET_STATE, that has id 1 and possible parameter values for this event are as in + * enum radio_state_t + */ +typedef enum +{ + NRF_802154_LOG_L_EVENT_DEFINE(CORE, SET_STATE, 1, radio_state_t) +} nrf_802154_drv_local_events_in_CORE_t; + +/** + * @brief List of GLOBAL EVENTS generated in 802.15.4 Driver modules + * + * Range of possible values for the 802.15.4 Driver modules has been indicated + * in nrf_802154_sl_log.h (see "Distribution of IDs for Debug Logs" in there) + */ +typedef enum +{ + NRF_802154_LOG_GLOBAL_EVENT_ID_RADIO_RESET = 1U + // Possible "RADIO_RESET" parameter values are : 0 (the only possible value) +} nrf_802154_drv_global_events_list_t; + +/** + * @brief List of all definitions that are needed for the correct presentation of debug logs + * + * All of the 'typedefs' defined above that are not used anywhere else in the code should occur + * in the union below, to ensure that information about them will appear in the final .elf file + */ +typedef union +{ + uint8_t dummy00tag; + nrf_802154_drv_modules_list_t dummy01tag; + nrf_802154_drv_global_events_list_t dummy02tag; + nrf_802154_drv_local_events_in_CORE_t dummy03tag; +} nrf_802154_drv_typedefs_to_save_in_elf_t; + +#endif /* NRF_802154_DEBUG_LOG_CODES_H_ */ diff --git a/src/nrf_802154_notification.h b/src/nrf_802154_notification.h index 3dd60b5..c2ef740 100644 --- a/src/nrf_802154_notification.h +++ b/src/nrf_802154_notification.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_NOTIFICATION_H__ diff --git a/src/nrf_802154_notification_direct.c b/src/nrf_802154_notification_direct.c index e9aacc1..4fe6c77 100644 --- a/src/nrf_802154_notification_direct.c +++ b/src/nrf_802154_notification_direct.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/nrf_802154_notification_swi.c b/src/nrf_802154_notification_swi.c index c440490..5af5de8 100644 --- a/src/nrf_802154_notification_swi.c +++ b/src/nrf_802154_notification_swi.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -36,25 +37,303 @@ #include "nrf_802154_notification.h" +#include #include #include #include "nrf_802154.h" +#include "nrf_802154_config.h" +#include "nrf_802154_peripherals.h" +#include "nrf_802154_queue.h" #include "nrf_802154_swi.h" +#include "nrf_802154_utils.h" +#include "hal/nrf_egu.h" + +/** Size of notification queue. + * + * One slot for each receive buffer, one for transmission, one for busy channel and one for energy + * detection. + * + * One slot is lost due to simplified queue implementation. + */ +#define NTF_QUEUE_SIZE ((NRF_802154_RX_BUFFERS + 3) + 1) + +#define NTF_INT NRF_EGU_INT_TRIGGERED0 ///< Label of notification interrupt. +#define NTF_TASK NRF_EGU_TASK_TRIGGER0 ///< Label of notification task. +#define NTF_EVENT NRF_EGU_EVENT_TRIGGERED0 ///< Label of notification event. + +/// Types of notifications in notification queue. +typedef enum +{ + NTF_TYPE_RECEIVED, ///< Frame received + NTF_TYPE_RECEIVE_FAILED, ///< Frame reception failed + NTF_TYPE_TRANSMITTED, ///< Frame transmitted + NTF_TYPE_TRANSMIT_FAILED, ///< Frame transmission failure + NTF_TYPE_ENERGY_DETECTED, ///< Energy detection procedure ended + NTF_TYPE_ENERGY_DETECTION_FAILED, ///< Energy detection procedure failed + NTF_TYPE_CCA, ///< CCA procedure ended + NTF_TYPE_CCA_FAILED, ///< CCA procedure failed +} nrf_802154_ntf_type_t; + +/// Notification data in the notification queue. +typedef struct +{ + nrf_802154_ntf_type_t type; ///< Notification type. + + union + { + struct + { + uint8_t * p_data; ///< Pointer to a buffer containing PHR and PSDU of the received frame. + int8_t power; ///< RSSI of received frame. + uint8_t lqi; ///< LQI of received frame. + } received; ///< Received frame details. + + struct + { + nrf_802154_rx_error_t error; ///< An error code that indicates reason of the failure. + } receive_failed; + + struct + { + const uint8_t * p_frame; ///< Pointer to frame that was transmitted. + uint8_t * p_ack; ///< Pointer to a buffer containing PHR and PSDU of the received ACK or NULL. + int8_t power; ///< RSSI of received ACK or 0. + uint8_t lqi; ///< LQI of received ACK or 0. + } transmitted; ///< Transmitted frame details. + + struct + { + const uint8_t * p_frame; ///< Pointer to frame that was requested to be transmitted, but failed. + nrf_802154_tx_error_t error; ///< An error code that indicates reason of the failure. + } transmit_failed; + + struct + { + int8_t result; ///< Energy detection result. + } energy_detected; ///< Energy detection details. + + struct + { + nrf_802154_ed_error_t error; ///< An error code that indicates reason of the failure. + } energy_detection_failed; ///< Energy detection failure details. + + struct + { + bool result; ///< CCA result. + } cca; ///< CCA details. + + struct + { + nrf_802154_cca_error_t error; ///< An error code that indicates reason of the failure. + } cca_failed; ///< CCA failure details. + } data; ///< Notification data depending on it's type. +} nrf_802154_ntf_data_t; + +static nrf_802154_queue_t m_notifications_queue; +static nrf_802154_ntf_data_t m_notifications_queue_memory[NTF_QUEUE_SIZE]; + +static volatile nrf_802154_mcu_critical_state_t m_mcu_cs; + +/** + * Enter notify block. + * + * This is a helper function used in all notification functions to atomically + * find an empty slot in the notification queue and allow atomic slot update. + * + * @return Pointer to an empty slot in the notification queue. + */ +static nrf_802154_ntf_data_t * ntf_enter(void) +{ + nrf_802154_mcu_critical_enter(m_mcu_cs); + + assert(!nrf_802154_queue_is_full(&m_notifications_queue)); + + return nrf_802154_queue_push_begin(&m_notifications_queue); +} + +/** + * Exit notify block. + * + * This is a helper function used in all notification functions to end atomic slot update + * and trigger SWI to process the notification from the slot. + */ +static void ntf_exit(void) +{ + nrf_802154_queue_push_commit(&m_notifications_queue); + + nrf_egu_task_trigger(NRF_802154_EGU_INSTANCE, NTF_TASK); + + nrf_802154_mcu_critical_exit(m_mcu_cs); +} + +/** + * @brief Notifies the next higher layer that a frame was received. + * + * The notification is triggered from the SWI priority level. + * + * @param[in] p_data Pointer to a buffer that contains PHR and PSDU of the received frame. + * @param[in] power RSSI measured during the frame reception. + * @param[in] lqi LQI that indicates the measured link quality during the frame reception. + */ +void swi_notify_received(uint8_t * p_data, int8_t power, uint8_t lqi) +{ + nrf_802154_ntf_data_t * p_slot = ntf_enter(); + + p_slot->type = NTF_TYPE_RECEIVED; + p_slot->data.received.p_data = p_data; + p_slot->data.received.power = power; + p_slot->data.received.lqi = lqi; + + ntf_exit(); +} + +/** + * @brief Notifies the next higher layer that the reception of a frame failed. + * + * @param[in] error Error code that indicates reason of the failure. + */ +void swi_notify_receive_failed(nrf_802154_rx_error_t error) +{ + nrf_802154_ntf_data_t * p_slot = ntf_enter(); + + p_slot->type = NTF_TYPE_RECEIVE_FAILED; + p_slot->data.receive_failed.error = error; + + ntf_exit(); +} + +/** + * @brief Notifies the next higher layer that a frame was transmitted + * + * The notification is triggered from the SWI priority level. + * + * @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the transmitted frame. + * @param[in] p_ack Pointer to a buffer that contains PHR and PSDU of ACK frame. NULL if ACK was + * not requested. + * @param[in] power RSSI of the received frame, or 0 if ACK was not requested. + * @param[in] lqi LQI of the received frame, or 0 if ACK was not requested. + */ +void swi_notify_transmitted(const uint8_t * p_frame, + uint8_t * p_ack, + int8_t power, + uint8_t lqi) +{ + nrf_802154_ntf_data_t * p_slot = ntf_enter(); + + p_slot->type = NTF_TYPE_TRANSMITTED; + p_slot->data.transmitted.p_frame = p_frame; + p_slot->data.transmitted.p_ack = p_ack; + p_slot->data.transmitted.power = power; + p_slot->data.transmitted.lqi = lqi; + + ntf_exit(); +} + +/** + * @brief Notifies the next higher layer that a frame was not transmitted from the SWI priority + * level. + * + * @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame that failed + * the transmission. + * @param[in] error Reason of the transmission failure. + */ +void swi_notify_transmit_failed(const uint8_t * p_frame, nrf_802154_tx_error_t error) +{ + nrf_802154_ntf_data_t * p_slot = ntf_enter(); + + p_slot->type = NTF_TYPE_TRANSMIT_FAILED; + p_slot->data.transmit_failed.p_frame = p_frame; + p_slot->data.transmit_failed.error = error; + + ntf_exit(); +} + +/** + * @brief Notifies the next higher layer that the energy detection procedure ended from + * the SWI priority level. + * + * @param[in] result Detected energy level. + */ +void swi_notify_energy_detected(uint8_t result) +{ + nrf_802154_ntf_data_t * p_slot = ntf_enter(); + + p_slot->type = NTF_TYPE_ENERGY_DETECTED; + p_slot->data.energy_detected.result = result; + + ntf_exit(); +} + +/** + * @brief Notifies the next higher layer that the energy detection procedure failed from + * the SWI priority level. + * + * @param[in] error Reason of the energy detection failure. + */ +void swi_notify_energy_detection_failed(nrf_802154_ed_error_t error) +{ + nrf_802154_ntf_data_t * p_slot = ntf_enter(); + + p_slot->type = NTF_TYPE_ENERGY_DETECTION_FAILED; + p_slot->data.energy_detection_failed.error = error; + + ntf_exit(); +} + +/** + * @brief Notifies the next higher layer that the Clear Channel Assessment (CCA) procedure ended. + * + * The notification is triggered from the SWI priority level. + * + * @param[in] channel_free If a free channel was detected. + */ +void swi_notify_cca(bool channel_free) +{ + nrf_802154_ntf_data_t * p_slot = ntf_enter(); + + p_slot->type = NTF_TYPE_CCA; + p_slot->data.cca.result = channel_free; + + ntf_exit(); +} + +/** + * @brief Notifies the next higher layer that the Clear Channel Assessment (CCA) procedure failed. + * + * The notification is triggered from the SWI priority level. + * + * @param[in] error Reason of the CCA failure. + */ +void swi_notify_cca_failed(nrf_802154_cca_error_t error) +{ + nrf_802154_ntf_data_t * p_slot = ntf_enter(); + + p_slot->type = NTF_TYPE_CCA_FAILED; + p_slot->data.cca_failed.error = error; + + ntf_exit(); +} void nrf_802154_notification_init(void) { + nrf_802154_queue_init(&m_notifications_queue, m_notifications_queue_memory, + sizeof(m_notifications_queue_memory), + sizeof(m_notifications_queue_memory[0])); + + nrf_egu_int_enable(NRF_802154_EGU_INSTANCE, NTF_INT); + nrf_802154_swi_init(); } void nrf_802154_notify_received(uint8_t * p_data, int8_t power, uint8_t lqi) { - nrf_802154_swi_notify_received(p_data, power, lqi); + swi_notify_received(p_data, power, lqi); } void nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error) { - nrf_802154_swi_notify_receive_failed(error); + swi_notify_receive_failed(error); } void nrf_802154_notify_transmitted(const uint8_t * p_frame, @@ -62,30 +341,128 @@ void nrf_802154_notify_transmitted(const uint8_t * p_frame, int8_t power, uint8_t lqi) { - nrf_802154_swi_notify_transmitted(p_frame, p_ack, power, lqi); + swi_notify_transmitted(p_frame, p_ack, power, lqi); } void nrf_802154_notify_transmit_failed(const uint8_t * p_frame, nrf_802154_tx_error_t error) { - nrf_802154_swi_notify_transmit_failed(p_frame, error); + swi_notify_transmit_failed(p_frame, error); } void nrf_802154_notify_energy_detected(uint8_t result) { - nrf_802154_swi_notify_energy_detected(result); + swi_notify_energy_detected(result); } void nrf_802154_notify_energy_detection_failed(nrf_802154_ed_error_t error) { - nrf_802154_swi_notify_energy_detection_failed(error); + swi_notify_energy_detection_failed(error); } void nrf_802154_notify_cca(bool is_free) { - nrf_802154_swi_notify_cca(is_free); + swi_notify_cca(is_free); } void nrf_802154_notify_cca_failed(nrf_802154_cca_error_t error) { - nrf_802154_swi_notify_cca_failed(error); + swi_notify_cca_failed(error); +} + +/**@brief Handles NTF_EVENT on NRF_802154_EGU_INSTANCE */ +static void irq_handler_ntf_event(void) +{ + while (!nrf_802154_queue_is_empty(&m_notifications_queue)) + { + nrf_802154_ntf_data_t * p_slot = + (nrf_802154_ntf_data_t *)nrf_802154_queue_pop_begin(&m_notifications_queue); + + switch (p_slot->type) + { + case NTF_TYPE_RECEIVED: +#if NRF_802154_USE_RAW_API + nrf_802154_received_raw(p_slot->data.received.p_data, + p_slot->data.received.power, + p_slot->data.received.lqi); +#else // NRF_802154_USE_RAW_API + nrf_802154_received(p_slot->data.received.p_data + RAW_PAYLOAD_OFFSET, + p_slot->data.received.p_data[RAW_LENGTH_OFFSET], + p_slot->data.received.power, + p_slot->data.received.lqi); +#endif + break; + + case NTF_TYPE_RECEIVE_FAILED: + nrf_802154_receive_failed(p_slot->data.receive_failed.error); + break; + + case NTF_TYPE_TRANSMITTED: + { +#if NRF_802154_USE_RAW_API + nrf_802154_transmitted_raw(p_slot->data.transmitted.p_frame, + p_slot->data.transmitted.p_ack, + p_slot->data.transmitted.power, + p_slot->data.transmitted.lqi); +#else // NRF_802154_USE_RAW_API + uint8_t * p_ack = NULL; + uint8_t length = 0; + + if (p_slot->data.transmitted.p_ack != NULL) + { + p_ack = p_slot->data.transmitted.p_ack + RAW_PAYLOAD_OFFSET; + length = p_slot->data.transmitted.p_ack[RAW_LENGTH_OFFSET]; + } + nrf_802154_transmitted(p_slot->data.transmitted.p_frame + RAW_PAYLOAD_OFFSET, + p_ack, + length, + p_slot->data.transmitted.power, + p_slot->data.transmitted.lqi); +#endif + } + break; + + case NTF_TYPE_TRANSMIT_FAILED: +#if NRF_802154_USE_RAW_API + nrf_802154_transmit_failed(p_slot->data.transmit_failed.p_frame, + p_slot->data.transmit_failed.error); +#else // NRF_802154_USE_RAW_API + nrf_802154_transmit_failed( + p_slot->data.transmit_failed.p_frame + RAW_PAYLOAD_OFFSET, + p_slot->data.transmit_failed.error); +#endif + break; + + case NTF_TYPE_ENERGY_DETECTED: + nrf_802154_energy_detected(p_slot->data.energy_detected.result); + break; + + case NTF_TYPE_ENERGY_DETECTION_FAILED: + nrf_802154_energy_detection_failed( + p_slot->data.energy_detection_failed.error); + break; + + case NTF_TYPE_CCA: + nrf_802154_cca_done(p_slot->data.cca.result); + break; + + case NTF_TYPE_CCA_FAILED: + nrf_802154_cca_failed(p_slot->data.cca_failed.error); + break; + + default: + assert(false); + } + + nrf_802154_queue_pop_commit(&m_notifications_queue); + } +} + +void nrf_802154_notification_swi_irq_handler(void) +{ + if (nrf_egu_event_check(NRF_802154_EGU_INSTANCE, NTF_EVENT)) + { + nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, NTF_EVENT); + + irq_handler_ntf_event(); + } } diff --git a/src/nrf_802154_nrfx_addons.h b/src/nrf_802154_nrfx_addons.h new file mode 100644 index 0000000..e7abcf6 --- /dev/null +++ b/src/nrf_802154_nrfx_addons.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "nrf.h" + +#if defined (NRF52840_XXAA) || defined(NRF52811_XXAA) || defined(NRF5340_XXAA_NETWORK) +#define ED_MIN_DBM (-92) ///< dBm value corresponding to value 0 in the EDSAMPLE register. +#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral. +#elif defined (NRF52833_XXAA) || defined(NRF52820_XXAA) +#define ED_MIN_DBM (-93) ///< dBm value corresponding to value 0 in the EDSAMPLE register. +#define ED_RESULT_FACTOR 5 ///< Factor needed to calculate the ED result based on the data from the RADIO peripheral. +#else +#error "Selected chip is not supported." +#endif diff --git a/src/nrf_802154_peripherals.h b/src/nrf_802154_peripherals.h index 8a66a55..3bd01e6 100644 --- a/src/nrf_802154_peripherals.h +++ b/src/nrf_802154_peripherals.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -41,7 +42,14 @@ #include "nrf_802154_config.h" #include "nrf_802154_debug.h" #include "nrf_802154_debug_core.h" -#include "fem/nrf_fem_protocol_api.h" + +#if defined(NRF52_SERIES) +#include "nrf_802154_peripherals_nrf52.h" +#elif defined(NRF5340_XXAA) +#include "nrf_802154_peripherals_nrf53.h" +#else +#error Unsupported chip family +#endif #ifdef __cplusplus extern "C" { @@ -106,83 +114,13 @@ extern "C" { #define NRF_802154_COUNTER_TIMER_INSTANCE \ NRFX_CONCAT_2(NRF_TIMER, NRF_802154_COUNTER_TIMER_INSTANCE_NO) -/** - * @def NRF_802154_SWI_EGU_INSTANCE_NO - * - * Number of the SWI EGU instance used by the driver to synchronize PPIs and for requests and - * notifications if SWI is in use. - * - */ -#ifndef NRF_802154_SWI_EGU_INSTANCE_NO - -#ifdef NRF52811_XXAA -#define NRF_802154_SWI_EGU_INSTANCE_NO 0 -#else -#define NRF_802154_SWI_EGU_INSTANCE_NO 3 -#endif - -#endif // NRF_802154_SWI_EGU_INSTANCE_NO - -/** - * @def NRF_802154_SWI_EGU_INSTANCE - * - * The SWI EGU instance used by the driver to synchronize PPIs and for requests and notifications if - * SWI is in use. - * - * @note This option is used by the core module regardless of the driver configuration. - * - */ -#define NRF_802154_SWI_EGU_INSTANCE NRFX_CONCAT_2(NRF_EGU, NRF_802154_SWI_EGU_INSTANCE_NO) - -/** - * @def NRF_802154_SWI_IRQ_HANDLER - * - * The SWI EGU IRQ handler used by the driver for requests and notifications if SWI is in use. - * - * @note This option is used when the driver uses SWI to process requests and notifications. - * - */ -#define NRF_802154_SWI_IRQ_HANDLER \ - NRFX_CONCAT_3(NRFX_CONCAT_3(SWI, NRF_802154_SWI_EGU_INSTANCE_NO, _EGU), \ - NRF_802154_SWI_EGU_INSTANCE_NO, \ - _IRQHandler) - -/** - * @def NRF_802154_SWI_IRQN - * - * The SWI EGU IRQ number used by the driver for requests and notifications if SWI is in use. - * - * @note This option is used when the driver uses SWI to process requests and notifications. - * - */ -#define NRF_802154_SWI_IRQN \ - NRFX_CONCAT_3(NRFX_CONCAT_3(SWI, NRF_802154_SWI_EGU_INSTANCE_NO, _EGU), \ - NRF_802154_SWI_EGU_INSTANCE_NO, \ - _IRQn) - -/** - * @def NRF_802154_RTC_INSTANCE_NO - * - * Number of the RTC instance used in the standalone timer driver implementation. - * - */ -#ifndef NRF_802154_RTC_INSTANCE_NO - -#ifdef NRF52811_XXAA -#define NRF_802154_RTC_INSTANCE_NO 0 -#else -#define NRF_802154_RTC_INSTANCE_NO 2 -#endif - -#endif // NRF_802154_RTC_INSTANCE_NO - /** * @def NRF_802154_RTC_INSTANCE * * The RTC instance used in the standalone timer driver implementation. * * @note This configuration is only applicable for the Low Power Timer Abstraction Layer - * implementation in nrf_802154_lp_timer.c. + * implementation in nrf_802154_lp_timer_nodrv.c. * */ #define NRF_802154_RTC_INSTANCE NRFX_CONCAT_2(NRF_RTC, NRF_802154_RTC_INSTANCE_NO) @@ -193,7 +131,7 @@ extern "C" { * The RTC interrupt handler name used in the standalone timer driver implementation. * * @note This configuration is only applicable for Low Power Timer Abstraction Layer implementation - * in nrf_802154_lp_timer.c. + * in nrf_802154_lp_timer_nodrv.c. * */ #define NRF_802154_RTC_IRQ_HANDLER NRFX_CONCAT_3(RTC, NRF_802154_RTC_INSTANCE_NO, _IRQHandler) @@ -204,217 +142,11 @@ extern "C" { * The RTC Interrupt number used in the standalone timer driver implementation. * * @note This configuration is only applicable for the Low Power Timer Abstraction Layer implementation - * in nrf_802154_lp_timer.c. + * in nrf_802154_lp_timer_nodrv.c. * */ #define NRF_802154_RTC_IRQN NRFX_CONCAT_3(RTC, NRF_802154_RTC_INSTANCE_NO, _IRQn) -/** - * @def NRF_802154_PPI_RADIO_DISABLED_TO_EGU - * - * The PPI channel that connects RADIO_DISABLED event to EGU task. - * - * @note This option is used by the core module regardless of the driver configuration. - * - */ -#ifndef NRF_802154_PPI_RADIO_DISABLED_TO_EGU -#define NRF_802154_PPI_RADIO_DISABLED_TO_EGU NRF_PPI_CHANNEL6 -#endif - -/** - * @def NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP - * - * The PPI channel that connects EGU event to RADIO_TXEN or RADIO_RXEN task. - * - * @note This option is used by the core module regardless of the driver configuration. - * - */ -#ifndef NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP -#define NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP NRF_PPI_CHANNEL7 -#endif - -/** - * @def NRF_802154_PPI_EGU_TO_TIMER_START - * - * The PPI channel that connects EGU event to TIMER_START task. - * - * @note This option is used by the core module regardless of the driver configuration. - * - */ -#ifndef NRF_802154_PPI_EGU_TO_TIMER_START -#define NRF_802154_PPI_EGU_TO_TIMER_START NRF_PPI_CHANNEL8 -#endif - -/** - * @def NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR - * - * The PPI channel that connects RADIO_CRCERROR event to TIMER_CLEAR task. - * - * @note This option is used by the core module regardless of the driver configuration. - * The peripheral is shared with @ref NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE - * and @ref NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN. - * - */ -#ifndef NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR -#define NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR NRF_PPI_CHANNEL9 -#endif - -/** - * @def NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE - * - * The PPI channel that connects RADIO_CCAIDLE event to the GPIOTE tasks used by the Frontend. - * - * @note This option is used by the core module regardless of the driver configuration. - * The peripheral is shared with @ref NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR - * and @ref NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN. - * - */ -#ifndef NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE -#define NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE NRF_PPI_CHANNEL9 -#endif - -/** - * @def NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN - * - * The PPI channel that connects TIMER_COMPARE event to RADIO_TXEN task. - * - * @note This option is used by the core module regardless of the driver configuration. - * The peripheral is shared with @ref NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR - * and @ref NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE. - * - */ -#ifndef NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN -#define NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN NRF_PPI_CHANNEL9 -#endif - -/** - * @def NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE - * - * The PPI channel that connects RADIO_CRCOK event with the task that disables the whole PPI group. - * - * @note This option is used by the core module regardless of the driver configuration. - * - */ -#ifndef NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE -#define NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE NRF_PPI_CHANNEL10 -#endif - -#ifdef NRF_802154_DISABLE_BCC_MATCHING - -/** - * @def NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT - * - * The PPI channel that connects RADIO_ADDRESS event to TIMER_COUNT task. - * - * @note This configuration is used only when the NRF_RADIO_EVENT_BCMATCH event handling is disabled - * (see @ref NRF_802154_DISABLE_BCC_MATCHING). - * - */ -#ifndef NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT -#define NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT NRF_PPI_CHANNEL11 -#endif - -/** - * @def NRF_802154_PPI_RADIO_CRCERROR_TO_COUNTER_CLEAR - * - * The PPI channel that connects RADIO_CRCERROR event to TIMER_CLEAR task. - * - * @note This option is used only when the NRF_RADIO_EVENT_BCMATCH event handling is disabled - * (see @ref NRF_802154_DISABLE_BCC_MATCHING). - * - */ -#ifndef NRF_802154_PPI_RADIO_CRCERROR_COUNTER_CLEAR -#define NRF_802154_PPI_RADIO_CRCERROR_COUNTER_CLEAR NRF_PPI_CHANNEL12 -#endif - -/** - * @def NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK - * - * Helper bit mask of PPI channels used additionally by the 802.15.4 driver when the BCC matching - * is disabled. - */ -#define NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK \ - ((1 << NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT) | \ - (1 << NRF_802154_PPI_RADIO_CRCERROR_COUNTER_CLEAR)) - -#else // NRF_802154_DISABLE_BCC_MATCHING - -#define NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK 0 - -#endif // NRF_802154_DISABLE_BCC_MATCHING - -#ifdef NRF_802154_FRAME_TIMESTAMP_ENABLED - -/** - * @def NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE - * - * The PPI channel that connects LP timer's COMPARE event to HP timer's TIMER_CAPTURE task. - * - * @note This option is used only when the timestamping feature is enabled - * (see @ref NRF_802154_FRAME_TIMESTAMP_ENABLED). - * - */ -#ifndef NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE -#define NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE NRF_PPI_CHANNEL13 -#endif - -/** - * @def NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE - * - * The PPI channel that connects provided event to HP timer's TIMER_CAPTURE task. - * - * @note This option is used only when the timestamping feature is enabled - * (see @ref NRF_802154_FRAME_TIMESTAMP_ENABLED). - * - */ -#ifndef NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE -#define NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE NRF_PPI_CHANNEL14 -#endif - -/** - * @def NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK - * - * Helper bit mask of PPI channels used by the 802.15.4 driver for timestamping. - */ -#define NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK \ - ((1 << NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE) | \ - (1 << NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE)) - -#else // NRF_802154_FRAME_TIMESTAMP_ENABLED - -#define NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK 0 - -#endif // NRF_802154_FRAME_TIMESTAMP_ENABLED - -/** - * @def NRF_802154_PPI_CORE_GROUP - * - * The PPI channel group used to disable self-disabling PPIs used by the core module. - * - * @note This option is used by the core module regardless of the driver configuration. - * - */ -#ifndef NRF_802154_PPI_CORE_GROUP -#define NRF_802154_PPI_CORE_GROUP NRF_PPI_CHANNEL_GROUP0 -#endif - -#ifdef NRF_802154_FRAME_TIMESTAMP_ENABLED - -/** - * @def NRF_802154_PPI_TIMESTAMP_GROUP - * - * The PPI channel group used to control PPIs used for timestamping. - * - * @note This option is used only when the timestamping feature is enabled - * (see @ref NRF_802154_FRAME_TIMESTAMP_ENABLED). - * - */ -#ifndef NRF_802154_PPI_TIMESTAMP_GROUP -#define NRF_802154_PPI_TIMESTAMP_GROUP NRF_PPI_CHANNEL_GROUP1 -#endif - -#endif // NRF_802154_FRAME_TIMESTAMP_ENABLED - /** * @def NRF_802154_TIMERS_USED_MASK * @@ -426,15 +158,6 @@ extern "C" { (1 << NRF_802154_COUNTER_TIMER_INSTANCE_NO)) #endif // NRF_802154_TIMERS_USED_MASK -/** - * @def NRF_802154_SWI_EGU_USED_MASK - * - * Bit mask of instances of SWI/EGU peripherals used by the 802.15.4 driver. - */ -#ifndef NRF_802154_SWI_EGU_USED_MASK -#define NRF_802154_SWI_EGU_USED_MASK (1 << NRF_802154_SWI_EGU_INSTANCE_NO) -#endif - /** * @def NRF_802154_RTC_USED_MASK * @@ -450,8 +173,7 @@ extern "C" { * Bit mask of GPIO pins used by the 802.15.4 driver. */ #ifndef NRF_802154_GPIO_PINS_USED_MASK -#define NRF_802154_GPIO_PINS_USED_MASK (NRF_802154_FEM_PINS_USED_MASK | \ - NRF_802154_DEBUG_PINS_USED_MASK) +#define NRF_802154_GPIO_PINS_USED_MASK NRF_802154_DEBUG_PINS_USED_MASK #endif // NRF_802154_GPIO_PINS_USED_MASK /** @@ -460,45 +182,9 @@ extern "C" { * Bit mask of GPIOTE peripherals used by the 802.15.4 driver. */ #ifndef NRF_802154_GPIOTE_CHANNELS_USED_MASK -#define NRF_802154_GPIOTE_CHANNELS_USED_MASK (NRF_802154_FEM_GPIOTE_CHANNELS_USED_MASK | \ - NRF_802154_DEBUG_GPIOTE_CHANNELS_USED_MASK) +#define NRF_802154_GPIOTE_CHANNELS_USED_MASK NRF_802154_DEBUG_GPIOTE_CHANNELS_USED_MASK #endif // NRF_802154_GPIOTE_CHANNELS_USED_MASK -/** - * @def NRF_80254_PPI_CHANNELS_USED_MASK - * - * Bit mask of PPI channels used by the 802.15.4 driver. - */ -#ifndef NRF_802154_PPI_CHANNELS_USED_MASK -#define NRF_802154_PPI_CHANNELS_USED_MASK ((1 << NRF_802154_PPI_RADIO_DISABLED_TO_EGU) | \ - (1 << NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP) | \ - (1 << NRF_802154_PPI_EGU_TO_TIMER_START) | \ - (1 << NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR) | \ - (1 << NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE) | \ - (1 << NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN) | \ - (1 << NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE) | \ - NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK | \ - NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK | \ - NRF_802154_FEM_PPI_CHANNELS_USED_MASK | \ - NRF_802154_DEBUG_PPI_CHANNELS_USED_MASK) -#endif // NRF_802154_PPI_CHANNELS_USED_MASK - -/** - * @def NRF_802154_PPI_GROUPS_USED_MASK - * - * Bit mask of PPI groups identifiers used by the 802.15.4 driver. - */ -#ifndef NRF_802154_PPI_GROUPS_USED_MASK - -#ifdef NRF_802154_FRAME_TIMESTAMP_ENABLED -#define NRF_802154_PPI_GROUPS_USED_MASK ((1 << NRF_802154_PPI_CORE_GROUP) | \ - (1 << NRF_802154_PPI_TIMESTAMP_GROUP)) -#else // NRF_802154_FRAME_TIMESTAMP_ENABLED -#define NRF_802154_PPI_GROUPS_USED_MASK (1 << NRF_802154_PPI_CORE_GROUP) -#endif // NRF_802154_FRAME_TIMESTAMP_ENABLED - -#endif // NRF_802154_PPI_GROUPS_USED_MASK - #ifdef __cplusplus } #endif diff --git a/src/nrf_802154_peripherals_nrf52.h b/src/nrf_802154_peripherals_nrf52.h new file mode 100644 index 0000000..3202140 --- /dev/null +++ b/src/nrf_802154_peripherals_nrf52.h @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Module that defines the 802.15.4 driver peripheral usage for nRF52 family. + * + */ + +#ifndef NRF_802154_PERIPHERALS_NRF52_H__ +#define NRF_802154_PERIPHERALS_NRF52_H__ + +#include +#include +#include "nrf_802154_config.h" +#include "nrf_802154_debug.h" +#include "hal/nrf_ppi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @def NRF_802154_EGU_INSTANCE_NO + * + * Number of the EGU instance used by the driver to synchronize PPIs and for requests and + * notifications if SWI is in use. + * + */ +#ifndef NRF_802154_EGU_INSTANCE_NO + +#if defined(NRF52811_XXAA) +#define NRF_802154_EGU_INSTANCE_NO 0 +#else +#define NRF_802154_EGU_INSTANCE_NO 3 +#endif + +#endif // NRF_802154_EGU_INSTANCE_NO + +/** + * @def NRF_802154_EGU_INSTANCE + * + * The EGU instance used by the driver to synchronize PPIs and for requests and notifications if + * SWI is in use. + * + * @note This option is used by the core module regardless of the driver configuration. + * + */ +#define NRF_802154_EGU_INSTANCE NRFX_CONCAT_2(NRF_EGU, NRF_802154_EGU_INSTANCE_NO) + +/** + * @def NRF_802154_EGU_IRQ_HANDLER + * + * The SWI EGU IRQ handler used by the driver for requests and notifications if SWI is in use. + * + * @note This option is used when the driver uses SWI to process requests and notifications. + * + */ +#define NRF_802154_EGU_IRQ_HANDLER \ + NRFX_CONCAT_3(NRFX_CONCAT_3(SWI, NRF_802154_EGU_INSTANCE_NO, _EGU), \ + NRF_802154_EGU_INSTANCE_NO, \ + _IRQHandler) + +/** + * @def NRF_802154_EGU_IRQN + * + * The SWI EGU IRQ number used by the driver for requests and notifications if SWI is in use. + * + * @note This option is used when the driver uses SWI to process requests and notifications. + * + */ +#define NRF_802154_EGU_IRQN \ + NRFX_CONCAT_3(NRFX_CONCAT_3(SWI, NRF_802154_EGU_INSTANCE_NO, _EGU), \ + NRF_802154_EGU_INSTANCE_NO, \ + _IRQn) + +/** + * @def NRF_802154_RTC_INSTANCE_NO + * + * Number of the RTC instance used in the standalone timer driver implementation. + * + */ +#ifndef NRF_802154_RTC_INSTANCE_NO + +#if defined(NRF52811_XXAA) || defined(NRF52820_XXAA) +#define NRF_802154_RTC_INSTANCE_NO 0 +#else +#define NRF_802154_RTC_INSTANCE_NO 2 +#endif + +#endif // NRF_802154_RTC_INSTANCE_NO + +/** + * @def NRF_802154_PPI_RADIO_DISABLED_TO_EGU + * + * The PPI channel that connects RADIO_DISABLED event to EGU task. + * + * @note This option is used by the core module regardless of the driver configuration. + * + */ +#ifndef NRF_802154_PPI_RADIO_DISABLED_TO_EGU +#define NRF_802154_PPI_RADIO_DISABLED_TO_EGU NRF_PPI_CHANNEL6 +#endif + +/** + * @def NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP + * + * The PPI channel that connects EGU event to RADIO_TXEN or RADIO_RXEN task. + * + * @note This option is used by the core module regardless of the driver configuration. + * + */ +#ifndef NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP +#define NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP NRF_PPI_CHANNEL7 +#endif + +/** + * @def NRF_802154_PPI_EGU_TO_TIMER_START + * + * The PPI channel that connects EGU event to TIMER_START task. + * + * @note This option is used by the core module regardless of the driver configuration. + * + */ +#ifndef NRF_802154_PPI_EGU_TO_TIMER_START +#define NRF_802154_PPI_EGU_TO_TIMER_START NRF_PPI_CHANNEL8 +#endif + +/** + * @def NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR + * + * The PPI channel that connects RADIO_CRCERROR event to TIMER_CLEAR task. + * + * @note This option is used by the core module regardless of the driver configuration. + * The peripheral is shared with @ref NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE + * and @ref NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN. + * + */ +#ifndef NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR +#define NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR NRF_PPI_CHANNEL9 +#endif + +/** + * @def NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE + * + * The PPI channel that connects RADIO_CCAIDLE event to the GPIOTE tasks used by the Frontend. + * + * @note This option is used by the core module regardless of the driver configuration. + * The peripheral is shared with @ref NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR + * and @ref NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN. + * + */ +#ifndef NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE +#define NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE NRF_PPI_CHANNEL9 +#endif + +/** + * @def NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN + * + * The PPI channel that connects TIMER_COMPARE event to RADIO_TXEN task. + * + * @note This option is used by the core module regardless of the driver configuration. + * The peripheral is shared with @ref NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR + * and @ref NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE. + * + */ +#ifndef NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN +#define NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN NRF_PPI_CHANNEL9 +#endif + +/** + * @def NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE + * + * The PPI channel that connects RADIO_CRCOK event with the task that disables the whole PPI group. + * + * @note This option is used by the core module regardless of the driver configuration. + * + */ +#ifndef NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE +#define NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE NRF_PPI_CHANNEL10 +#endif + +#if NRF_802154_DISABLE_BCC_MATCHING + +/** + * @def NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT + * + * The PPI channel that connects RADIO_ADDRESS event to TIMER_COUNT task. + * + * @note This configuration is used only when the NRF_RADIO_EVENT_BCMATCH event handling is disabled + * (see @ref NRF_802154_DISABLE_BCC_MATCHING). + * + */ +#ifndef NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT +#define NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT NRF_PPI_CHANNEL11 +#endif + +/** + * @def NRF_802154_PPI_RADIO_CRCERROR_TO_COUNTER_CLEAR + * + * The PPI channel that connects RADIO_CRCERROR event to TIMER_CLEAR task. + * + * @note This option is used only when the NRF_RADIO_EVENT_BCMATCH event handling is disabled + * (see @ref NRF_802154_DISABLE_BCC_MATCHING). + * + */ +#ifndef NRF_802154_PPI_RADIO_CRCERROR_COUNTER_CLEAR +#define NRF_802154_PPI_RADIO_CRCERROR_COUNTER_CLEAR NRF_PPI_CHANNEL12 +#endif + +/** + * @def NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK + * + * Helper bit mask of PPI channels used additionally by the 802.15.4 driver when the BCC matching + * is disabled. + */ +#define NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK \ + ((1 << NRF_802154_PPI_RADIO_ADDR_TO_COUNTER_COUNT) | \ + (1 << NRF_802154_PPI_RADIO_CRCERROR_COUNTER_CLEAR)) + +#else // NRF_802154_DISABLE_BCC_MATCHING + +/** + * @def NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC + * + * The PPI channel that connects RADIO_SYNC event to EGU_SYNC task. + * EGU_SYNC task belongs to one of EGU channels + * + * @note This configuration is used only when the NRF_RADIO_EVENT_BCMATCH event handling is enabled + * (see @ref NRF_802154_DISABLE_BCC_MATCHING). + * + */ +#ifndef NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC +#define NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC NRF_PPI_CHANNEL11 +#endif + +#define NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK \ + (1 << NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC) + +#endif // NRF_802154_DISABLE_BCC_MATCHING + +#ifdef NRF_802154_FRAME_TIMESTAMP_ENABLED + +/** + * @def NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE + * + * The PPI channel that connects LP timer's COMPARE event to HP timer's TIMER_CAPTURE task. + * + * @note This option is used only when the timestamping feature is enabled + * (see @ref NRF_802154_FRAME_TIMESTAMP_ENABLED). + * + */ +#ifndef NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE +#define NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE NRF_PPI_CHANNEL13 +#endif + +/** + * @def NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE + * + * The PPI channel that connects provided event to HP timer's TIMER_CAPTURE task. + * + * @note This option is used only when the timestamping feature is enabled + * (see @ref NRF_802154_FRAME_TIMESTAMP_ENABLED). + * + */ +#ifndef NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE +#define NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE NRF_PPI_CHANNEL14 +#endif + +/** + * @def NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK + * + * Helper bit mask of PPI channels used by the 802.15.4 driver for timestamping. + */ +#define NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK \ + ((1 << NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE) | \ + (1 << NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE)) + +#else // NRF_802154_FRAME_TIMESTAMP_ENABLED + +#define NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK 0 + +#endif // NRF_802154_FRAME_TIMESTAMP_ENABLED + +/** + * @def NRF_802154_PPI_CORE_GROUP + * + * The PPI channel group used to disable self-disabling PPIs used by the core module. + * + * @note This option is used by the core module regardless of the driver configuration. + * + */ +#ifndef NRF_802154_PPI_CORE_GROUP +#define NRF_802154_PPI_CORE_GROUP NRF_PPI_CHANNEL_GROUP0 +#endif + +/** + * @def NRF_802154_PPI_ABORT_GROUP + * + * The PPI channel group used to break PPI connections related with FEM, when the abort condition occurs. + * + */ +#ifndef NRF_802154_PPI_ABORT_GROUP +#define NRF_802154_PPI_ABORT_GROUP NRF_PPI_CHANNEL_GROUP1 +#endif + +/** + * @def NRF_802154_EGU_USED_MASK + * + * Bit mask of instances of SWI/EGU peripherals used by the 802.15.4 driver. + */ +#ifndef NRF_802154_EGU_USED_MASK +#define NRF_802154_EGU_USED_MASK (1 << NRF_802154_EGU_INSTANCE_NO) +#endif + +/** + * @def NRF_80254_PPI_CHANNELS_USED_MASK + * + * Bit mask of PPI channels used by the 802.15.4 driver. + */ +#ifndef NRF_802154_PPI_CHANNELS_USED_MASK +#define NRF_802154_PPI_CHANNELS_USED_MASK ((1 << NRF_802154_PPI_RADIO_DISABLED_TO_EGU) | \ + (1 << NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP) | \ + (1 << NRF_802154_PPI_EGU_TO_TIMER_START) | \ + (1 << NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR) | \ + (1 << NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE) | \ + (1 << NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN) | \ + (1 << NRF_802154_PPI_RADIO_CRCOK_TO_PPI_GRP_DISABLE) | \ + NRF_802154_DISABLE_BCC_MATCHING_PPI_CHANNELS_USED_MASK | \ + NRF_802154_TIMESTAMP_PPI_CHANNELS_USED_MASK | \ + NRF_802154_FEM_PPI_CHANNELS_USED_MASK | \ + NRF_802154_DEBUG_PPI_CHANNELS_USED_MASK) +#endif // NRF_802154_PPI_CHANNELS_USED_MASK + +/** + * @def NRF_802154_PPI_GROUPS_USED_MASK + * + * Bit mask of PPI groups identifiers used by the 802.15.4 driver. + */ +#ifndef NRF_802154_PPI_GROUPS_USED_MASK +#define NRF_802154_PPI_GROUPS_USED_MASK ((1 << NRF_802154_PPI_CORE_GROUP) | \ + (1 << NRF_802154_PPI_ABORT_GROUP) ) +#endif // NRF_802154_PPI_GROUPS_USED_MASK + +#ifdef __cplusplus +} +#endif + +#endif // NRF_802154_PERIPHERALS_NRF52_H__ diff --git a/src/nrf_802154_peripherals_nrf53.h b/src/nrf_802154_peripherals_nrf53.h new file mode 100644 index 0000000..3314b54 --- /dev/null +++ b/src/nrf_802154_peripherals_nrf53.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Module that defines the 802.15.4 driver peripheral usage for nRF53 family. + * + */ + +#ifndef NRF_802154_PERIPHERALS_NRF53_H__ +#define NRF_802154_PERIPHERALS_NRF53_H__ + +#include +#include +#include "nrf_802154_config.h" +#include "nrf_802154_debug.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @def NRF_802154_EGU_INSTANCE_NO + * + * Id of the EGU instance used by the driver to synchronize DPPIs and for requests and + * notifications if SWI is in use. + * + */ +#ifndef NRF_802154_EGU_INSTANCE_NO +#define NRF_802154_EGU_INSTANCE_NO 0 +#endif + +/** + * @def NRF_802154_EGU_INSTANCE + * + * The EGU instance used by the driver to synchronize PPIs and for requests and notifications if + * SWI is in use. + * + * @note This option is used by the core module regardless of the driver configuration. + * + */ +#define NRF_802154_EGU_INSTANCE NRFX_CONCAT_2(NRF_EGU, NRF_802154_EGU_INSTANCE_NO) + +/** + * @def NRF_802154_EGU_IRQ_HANDLER + * + * The EGU IRQ handler used by the driver for requests and notifications if SWI is in use. + * + * @note This option is used when the driver uses SWI to process requests and notifications. + * + */ +#define NRF_802154_EGU_IRQ_HANDLER \ + NRFX_CONCAT_3(EGU, NRF_802154_EGU_INSTANCE_NO, _IRQHandler) + +/** + * @def NRF_802154_EGU_IRQN + * + * The SWI EGU IRQ number used by the driver for requests and notifications if SWI is in use. + * + * @note This option is used when the driver uses SWI to process requests and notifications. + * + */ +#define NRF_802154_EGU_IRQN \ + NRFX_CONCAT_3(EGU, NRF_802154_EGU_INSTANCE_NO, _IRQn) + +/** + * @def NRF_802154_EGU_USED_MASK + * + * Bit mask of instances of SWI/EGU peripherals used by the 802.15.4 driver. + */ +#ifndef NRF_802154_EGU_USED_MASK +#define NRF_802154_EGU_USED_MASK (1 << NRF_802154_EGU_INSTANCE_NO) +#endif + +/** + * @def NRF_802154_RTC_INSTANCE_NO + * + * Number of the RTC instance used in the standalone timer driver implementation. + * + */ +#ifndef NRF_802154_RTC_INSTANCE_NO +#define NRF_802154_RTC_INSTANCE_NO 2 +#endif + +/** + * @def NRF_802154_DPPI_RADIO_DISABLED_TO_EGU + * + * The DPPI channel that connects RADIO_DISABLED event to EGU task. + * + * @note This option is used by the core module regardless of the driver configuration. + * + */ +#ifndef NRF_802154_DPPI_RADIO_DISABLED_TO_EGU +#define NRF_802154_DPPI_RADIO_DISABLED_TO_EGU 6U +#endif + +/** + * @def NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP + * + * The DPPI channel that connects EGU event to RADIO_TXEN or RADIO_RXEN task. + * + * @note This option is used by the core module regardless of the driver configuration. + * The peripheral is shared with @ref NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP. + * + */ +#ifndef NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP +#define NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP 7U +#endif + +/** + * @def NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN + * + * The DPPI channel that connects TIMER_COMPARE event to RADIO_TXEN task. + * + * @note This option is used by the core module regardless of the driver configuration. + * The peripheral is shared with @ref NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP. + * + */ +#ifndef NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN +#define NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN 7U +#endif + +/** + * @def NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC + * + * The DPPI channel that connects RADIO_SYNC event to EGU_SYNC task. + * EGU_SYNC task belongs to one of EGU channels + * + */ +#ifndef NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC +#define NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC 8U +#endif + +#ifdef __cplusplus +} +#endif + +#endif // NRF_802154_PERIPHERALS_NRF53_H__ diff --git a/src/nrf_802154_pib.c b/src/nrf_802154_pib.c index 07f56ac..da24de8 100644 --- a/src/nrf_802154_pib.c +++ b/src/nrf_802154_pib.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -43,20 +44,61 @@ #include "nrf_802154_config.h" #include "nrf_802154_const.h" +#include "nrf_802154_nrfx_addons.h" #include "nrf_802154_utils.h" #include "fal/nrf_802154_fal.h" +#define CSMACA_BE_MAXIMUM 8 ///< The maximum allowed CSMA-CA backoff exponent (BE) that results from the implementation + +typedef struct +{ + nrf_802154_coex_rx_request_mode_t rx_request_mode; ///< Coex request mode in receive operation. + nrf_802154_coex_tx_request_mode_t tx_request_mode; ///< Coex request mode in transmit operation. +} nrf_802154_pib_coex_t; + +#if NRF_802154_CSMA_CA_ENABLED +typedef struct +{ + uint8_t min_be; // The minimum value of the backoff exponent (BE) in the CSMA-CA algorithm + uint8_t max_be; // The maximum value of the backoff exponent (BE) in the CSMA-CA algorithm + uint8_t max_backoffs; // The maximum number of backoffs that the CSMA-CA algorithm will attempt before declaring a channel access failure. +} nrf_802154_pib_csmaca_t; + +#endif // NRF_802154_CSMA_CA_ENABLED + +#if NRF_802154_IFS_ENABLED +typedef struct +{ + nrf_802154_ifs_mode_t mode; ///< Mode of Interframe Space insertion. + uint16_t min_sifs_period_us; ///< Minimum Short Interframe Space period in us. + uint16_t min_lifs_period_us; ///< Minimum Long Interframe Space period in us. +} nrf_802154_pib_ifs_t; + +#endif // NRF_802154_IFS_ENABLED + typedef struct { - int8_t tx_power; ///< Transmit power. - uint8_t pan_id[PAN_ID_SIZE]; ///< Pan Id of this node. - uint8_t short_addr[SHORT_ADDRESS_SIZE]; ///< Short Address of this node. - uint8_t extended_addr[EXTENDED_ADDRESS_SIZE]; ///< Extended Address of this node. - nrf_802154_cca_cfg_t cca; ///< CCA mode and thresholds. - bool promiscuous : 1; ///< Indicating if radio is in promiscuous mode. - bool auto_ack : 1; ///< Indicating if auto ACK procedure is enabled. - bool pan_coord : 1; ///< Indicating if radio is configured as the PAN coordinator. - uint8_t channel : 5; ///< Channel on which the node receives messages. + int8_t tx_power; ///< Transmit power. + uint8_t pan_id[PAN_ID_SIZE]; ///< Pan Id of this node. + uint8_t short_addr[SHORT_ADDRESS_SIZE]; ///< Short Address of this node. + uint8_t extended_addr[EXTENDED_ADDRESS_SIZE]; ///< Extended Address of this node. + nrf_802154_cca_cfg_t cca; ///< CCA mode and thresholds. + bool promiscuous : 1; ///< Indicating if radio is in promiscuous mode. + bool auto_ack : 1; ///< Indicating if auto ACK procedure is enabled. + bool pan_coord : 1; ///< Indicating if radio is configured as the PAN coordinator. + uint8_t channel : 5; ///< Channel on which the node receives messages. + nrf_802154_pib_coex_t coex; ///< Coex-related fields. + +#if NRF_802154_CSMA_CA_ENABLED + nrf_802154_pib_csmaca_t csmaca; ///< CSMA-CA related fields. + +#endif + +#if NRF_802154_IFS_ENABLED + nrf_802154_pib_ifs_t ifs; ///< IFS-related fields. + +#endif + } nrf_802154_pib_data_t; // Static variables. @@ -88,7 +130,9 @@ static nrf_radio_txpower_t to_radio_tx_power_convert(int8_t integer_tx_power) #if defined(RADIO_TXPOWER_TXPOWER_Pos3dBm) NRF_RADIO_TXPOWER_POS3DBM, /**< 3 dBm. */ #endif +#if defined(RADIO_TXPOWER_TXPOWER_Pos4dBm) NRF_RADIO_TXPOWER_POS4DBM, /**< 4 dBm. */ +#endif #if defined(RADIO_TXPOWER_TXPOWER_Pos5dBm) NRF_RADIO_TXPOWER_POS5DBM, /**< 5 dBm. */ #endif @@ -120,6 +164,64 @@ static nrf_radio_txpower_t to_radio_tx_power_convert(int8_t integer_tx_power) return radio_tx_power; } +/** + * @brief Checks if provided Coex transmit request mode is supported. + * + * @param[in] mode Coex transmit request mode to check. + * + * @retval true When value provided by @p mode param is supported. + * @retval false Otherwise. + */ +static bool coex_tx_request_mode_is_supported(nrf_802154_coex_tx_request_mode_t mode) +{ + bool result = false; + + switch (mode) + { + case NRF_802154_COEX_TX_REQUEST_MODE_FRAME_READY: + case NRF_802154_COEX_TX_REQUEST_MODE_CCA_START: + case NRF_802154_COEX_TX_REQUEST_MODE_CCA_DONE: + result = true; + break; + + default: + break; + } + + return result; +} + +/** + * @brief Checks if provided Coex receive request mode is supported. + * + * @param[in] mode Coex receive request mode to check. + * + * @retval true When value provided by @p mode param is supported. + * @retval false Otherwise. + */ +static bool coex_rx_request_mode_is_supported(nrf_802154_coex_rx_request_mode_t mode) +{ + bool result = false; + + switch (mode) + { +#if !NRF_802154_DISABLE_BCC_MATCHING && defined(RADIO_INTENSET_SYNC_Msk) + case NRF_802154_COEX_RX_REQUEST_MODE_ENERGY_DETECTION: +#endif + case NRF_802154_COEX_RX_REQUEST_MODE_PREAMBLE: +#if !NRF_802154_DISABLE_BCC_MATCHING + case NRF_802154_COEX_RX_REQUEST_MODE_DESTINED: +#endif + result = true; + break; + + default: + break; + } + + return result; +} + void nrf_802154_pib_init(void) { m_data.promiscuous = false; @@ -136,6 +238,25 @@ void nrf_802154_pib_init(void) m_data.cca.ed_threshold = NRF_802154_CCA_ED_THRESHOLD_DEFAULT; m_data.cca.corr_threshold = NRF_802154_CCA_CORR_THRESHOLD_DEFAULT; m_data.cca.corr_limit = NRF_802154_CCA_CORR_LIMIT_DEFAULT; + +#if NRF_802154_DISABLE_BCC_MATCHING + m_data.coex.rx_request_mode = NRF_802154_COEX_RX_REQUEST_MODE_PREAMBLE; +#else + m_data.coex.rx_request_mode = NRF_802154_COEX_RX_REQUEST_MODE_DESTINED; +#endif + m_data.coex.tx_request_mode = NRF_802154_COEX_TX_REQUEST_MODE_FRAME_READY; + +#if NRF_802154_CSMA_CA_ENABLED + m_data.csmaca.min_be = NRF_802154_CSMA_CA_MIN_BE_DEFAULT; + m_data.csmaca.max_be = NRF_802154_CSMA_CA_MAX_BE_DEFAULT; + m_data.csmaca.max_backoffs = NRF_802154_CSMA_CA_MAX_CSMA_BACKOFFS_DEFAULT; +#endif // NRF_802154_CSMA_CA_ENABLED + +#if NRF_802154_IFS_ENABLED + m_data.ifs.min_sifs_period_us = MIN_SIFS_PERIOD_US; + m_data.ifs.min_lifs_period_us = MIN_LIFS_PERIOD_US; + m_data.ifs.mode = NRF_802154_IFS_MODE_DISABLED; +#endif // NRF_802154_IFS_ENABLED } bool nrf_802154_pib_promiscuous_get(void) @@ -249,3 +370,129 @@ void nrf_802154_pib_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg) { memcpy(p_cca_cfg, &m_data.cca, sizeof(m_data.cca)); } + +bool nrf_802154_pib_coex_rx_request_mode_set(nrf_802154_coex_rx_request_mode_t mode) +{ + bool result = coex_rx_request_mode_is_supported(mode); + + if (result) + { + m_data.coex.rx_request_mode = mode; + } + + return result; +} + +nrf_802154_coex_rx_request_mode_t nrf_802154_pib_coex_rx_request_mode_get(void) +{ + return m_data.coex.rx_request_mode; +} + +bool nrf_802154_pib_coex_tx_request_mode_set(nrf_802154_coex_tx_request_mode_t mode) +{ + bool result = coex_tx_request_mode_is_supported(mode); + + if (result) + { + m_data.coex.tx_request_mode = mode; + } + + return result; +} + +nrf_802154_coex_tx_request_mode_t nrf_802154_pib_coex_tx_request_mode_get(void) +{ + return m_data.coex.tx_request_mode; +} + +#if NRF_802154_CSMA_CA_ENABLED +bool nrf_802154_pib_csmaca_min_be_set(uint8_t min_be) +{ + bool result = (min_be <= CSMACA_BE_MAXIMUM); + + if (result) + { + m_data.csmaca.min_be = min_be; + } + + return result; +} + +uint8_t nrf_802154_pib_csmaca_min_be_get(void) +{ + return m_data.csmaca.min_be; +} + +bool nrf_802154_pib_csmaca_max_be_set(uint8_t max_be) +{ + bool result = (max_be <= CSMACA_BE_MAXIMUM); + + if (result) + { + m_data.csmaca.max_be = max_be; + } + + return result; +} + +uint8_t nrf_802154_pib_csmaca_max_be_get(void) +{ + return m_data.csmaca.max_be; +} + +void nrf_802154_pib_csmaca_max_backoffs_set(uint8_t max_backoffs) +{ + m_data.csmaca.max_backoffs = max_backoffs; +} + +uint8_t nrf_802154_pib_csmaca_max_backoffs_get(void) +{ + return m_data.csmaca.max_backoffs; +} + +#endif // NRF_802154_CSMA_CA_ENABLED + +#if NRF_802154_IFS_ENABLED +nrf_802154_ifs_mode_t nrf_802154_pib_ifs_mode_get(void) +{ + return m_data.ifs.mode; +} + +bool nrf_802154_pib_ifs_mode_set(nrf_802154_ifs_mode_t mode) +{ + switch (mode) + { + case NRF_802154_IFS_MODE_DISABLED: + case NRF_802154_IFS_MODE_MATCHING_ADDRESSES: + case NRF_802154_IFS_MODE_ALWAYS: + m_data.ifs.mode = mode; + return true; + + default: + return false; + } +} + +uint16_t nrf_802154_pib_ifs_min_sifs_period_get(void) +{ + return m_data.ifs.min_sifs_period_us; +} + +void nrf_802154_pib_ifs_min_sifs_period_set(uint16_t period) +{ + assert(period >= TURNAROUND_TIME); + + m_data.ifs.min_sifs_period_us = period; +} + +uint16_t nrf_802154_pib_ifs_min_lifs_period_get(void) +{ + return m_data.ifs.min_lifs_period_us; +} + +void nrf_802154_pib_ifs_min_lifs_period_set(uint16_t period) +{ + m_data.ifs.min_lifs_period_us = period; +} + +#endif // NRF_802154_IFS_ENABLED diff --git a/src/nrf_802154_pib.h b/src/nrf_802154_pib.h index 8aa24f9..0e93462 100644 --- a/src/nrf_802154_pib.h +++ b/src/nrf_802154_pib.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -186,6 +187,141 @@ void nrf_802154_pib_cca_cfg_set(const nrf_802154_cca_cfg_t * p_cca_cfg); */ void nrf_802154_pib_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg); +/** + * @brief Sets Coex request mode used in receive operations. + * + * @param[in] mode Coex receive request mode. + * + * @retval true When value provided by @p mode param is supported. + * @retval false Otherwise. + */ +bool nrf_802154_pib_coex_rx_request_mode_set(nrf_802154_coex_rx_request_mode_t mode); + +/** + * @brief Gets Coex request mode used in receive operations. + * + * @return Current Coex receive request mode. + */ +nrf_802154_coex_rx_request_mode_t nrf_802154_pib_coex_rx_request_mode_get(void); + +/** + * @brief Sets Coex request mode used in transmit operations. + * + * @param[in] mode Coex transmit request mode. + * + * @retval true When value provided by @p mode param is supported. + * @retval false Otherwise. + */ +bool nrf_802154_pib_coex_tx_request_mode_set(nrf_802154_coex_tx_request_mode_t mode); + +/** + * @brief Gets Coex request mode used in transmit operations. + * + * @return Current Coex transmit request mode. + */ +nrf_802154_coex_tx_request_mode_t nrf_802154_pib_coex_tx_request_mode_get(void); + +#if NRF_802154_CSMA_CA_ENABLED +/** + * @brief Sets the minimum value of the backoff exponent (BE) in the CSMA-CA algorithm. + * + * @param[in] min_be Minimum value of the backoff exponent. + * + * @retval true When value provided by @p min_be does not exceed the implementation limit ( <= 8). + * @retval false Otherwise. + */ +bool nrf_802154_pib_csmaca_min_be_set(uint8_t min_be); + +/** + * @brief Gets the minimum value of the backoff exponent (BE) in the CSMA-CA algorithm. + * + * @return Current minimum value of the backoff exponent. + */ +uint8_t nrf_802154_pib_csmaca_min_be_get(void); + +/** + * @brief Sets the maximum value of the backoff exponent (BE) in the CSMA-CA algorithm. + * + * @param[in] max_be Maximum value of the backoff exponent. + * + * @retval true When value provided by @p max_be does not exceed the implementation limit ( <= 8). + * @retval false Otherwise. + */ +bool nrf_802154_pib_csmaca_max_be_set(uint8_t max_be); + +/** + * @brief Gets the maximum value of the backoff exponent (BE) in the CSMA-CA algorithm. + * + * @return Current maximum value of the backoff exponent. + */ +uint8_t nrf_802154_pib_csmaca_max_be_get(void); + +/** + * @brief Sets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring + * a channel access failure. + * + * @param[in] max_backoffs Maximum number of backoffs. + */ +void nrf_802154_pib_csmaca_max_backoffs_set(uint8_t max_backoffs); + +/** + * @brief Gets the maximum number of backoffs the CSMA-CA algorithm will attempt before declaring + * a channel access failure. + * + * @return Current maximum number of backoffs. + */ +uint8_t nrf_802154_pib_csmaca_max_backoffs_get(void); +#endif // NRF_802154_CSMA_CA_ENABLED + +#if NRF_802154_IFS_ENABLED +/** + * @brief Gets IFS operation mode. + * + * @return Current IFS operation mode. Refer to @ref nrf_802154_ifs_mode_t for details. + */ +nrf_802154_ifs_mode_t nrf_802154_pib_ifs_mode_get(void); + +/** + * @brief Sets IFS operation mode. + * + * @param[in] mode IFS operation mode. Refer to @ref nrf_802154_ifs_mode_t for details. + * + * @retval true The update of PIB was successful. + * @retval false The update of PIB failed due to the unsupported mode. + */ +bool nrf_802154_pib_ifs_mode_set(nrf_802154_ifs_mode_t mode); + +/** + * @brief Gets Short IFS period in microseconds. + * + * @return Current Short IFS period in microseconds. + */ +uint16_t nrf_802154_pib_ifs_min_sifs_period_get(void); + +/** + * @brief Sets Short IFS period in microseconds. + * + * @param[in] period Short IFS period in microseconds. + * + * @note The period cannot be smaller than aTurnaroundTime. + */ +void nrf_802154_pib_ifs_min_sifs_period_set(uint16_t period); + +/** + * @brief Gets Long IFS period in microseconds. + * + * @return Current Long IFS period in microseconds. + */ +uint16_t nrf_802154_pib_ifs_min_lifs_period_get(void); + +/** + * @brief Sets Long IFS period in microseconds. + * + * @param[in] period Long IFS period in microseconds. + */ +void nrf_802154_pib_ifs_min_lifs_period_set(uint16_t period); +#endif // NRF_802154_IFS_ENABLED + #ifdef __cplusplus } #endif diff --git a/src/nrf_802154_priority_drop.h b/src/nrf_802154_priority_drop.h deleted file mode 100644 index 596c2c0..0000000 --- a/src/nrf_802154_priority_drop.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef NRF_802154_PRIORITY_DROP_H__ -#define NRF_802154_PRIORITY_DROP_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup nrf_802154_priority_drop 802.15.4 driver procedures with lower priority - * @{ - * @ingroup nrf_802154 - * @brief Internal procedures of the 802.15.4 driver that should be called with lower priority than - * the caller's priority. - */ - -/** - * @brief Initializes the notification module. - */ -void nrf_802154_priority_drop_init(void); - -/** - * @brief Requests the stop of the high frequency clock. - * - * @note This function must be called through this module to prevent calling it from the arbiter - * context. - */ -void nrf_802154_priority_drop_hfclk_stop(void); - -/** - * @brief Terminates the requesting of the high frequency clock stop procedure. - * - * Function used to to terminate the HFClk stop procedure requested by the previous call to - * @rev nrf_802154_priority_drop_hfclk_stop. The HFClk stop procedure is terminated only if it has - * not been started. - */ -void nrf_802154_priority_drop_hfclk_stop_terminate(void); - -/** - *@} - **/ - -#ifdef __cplusplus -} -#endif - -#endif // NRF_802154_PRIORITY_DROP_H__ diff --git a/src/nrf_802154_priority_drop_direct.c b/src/nrf_802154_priority_drop_direct.c deleted file mode 100644 index fe79f0a..0000000 --- a/src/nrf_802154_priority_drop_direct.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements procedures that should be called with lower priority than caller in - * the nrf 802.15.4 radio driver. - * - */ - -#include "nrf_802154_priority_drop.h" - -#include "platform/clock/nrf_802154_clock.h" - -void nrf_802154_priority_drop_init(void) -{ - // Intentionally empty -} - -void nrf_802154_priority_drop_hfclk_stop(void) -{ - nrf_802154_clock_hfclk_stop(); -} - -void nrf_802154_priority_drop_hfclk_stop_terminate(void) -{ - // Intentionally empty: - // nrf_802154_priority_drop_hfclk_stop is synchronous and cannot be terminated. -} diff --git a/src/nrf_802154_priority_drop_swi.c b/src/nrf_802154_priority_drop_swi.c index ae2a31c..cda0935 100644 --- a/src/nrf_802154_priority_drop_swi.c +++ b/src/nrf_802154_priority_drop_swi.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -35,21 +36,69 @@ * */ -#include "nrf_802154_priority_drop.h" +#include + +#include "nrf_802154_config.h" +#include "nrf_802154_peripherals.h" +#include "rsch/nrf_802154_rsch_prio_drop.h" #include "nrf_802154_swi.h" +#include "hal/nrf_egu.h" +#include "platform/clock/nrf_802154_clock.h" + +#define HFCLK_STOP_INT NRF_EGU_INT_TRIGGERED1 ///< Label of HFClk stop interrupt. +#define HFCLK_STOP_TASK NRF_EGU_TASK_TRIGGER1 ///< Label of HFClk stop task. +#define HFCLK_STOP_EVENT NRF_EGU_EVENT_TRIGGERED1 ///< Label of HFClk stop event. + +/** + * @brief Requests a stop of the HF clock. + * + * The notification is triggered from the SWI priority level. + * + * @note This function is to be called through notification module to prevent calling it from + * the arbiter context. + */ +static void swi_hfclk_stop(void) +{ + assert(!nrf_egu_event_check(NRF_802154_EGU_INSTANCE, HFCLK_STOP_EVENT)); + + nrf_egu_task_trigger(NRF_802154_EGU_INSTANCE, HFCLK_STOP_TASK); +} -void nrf_802154_priority_drop_init(void) +/** + * @brief Terminates the stopping of the HF clock. + * + * @note This function terminates the stopping of the HF clock only if it has not been performed + * yet. + */ +static void swi_hfclk_stop_terminate(void) +{ + nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, HFCLK_STOP_EVENT); +} + +void nrf_802154_rsch_prio_drop_init(void) { + nrf_egu_int_enable(NRF_802154_EGU_INSTANCE, HFCLK_STOP_INT); + nrf_802154_swi_init(); } -void nrf_802154_priority_drop_hfclk_stop(void) +void nrf_802154_rsch_prio_drop_hfclk_stop(void) { - nrf_802154_swi_hfclk_stop(); + swi_hfclk_stop(); } -void nrf_802154_priority_drop_hfclk_stop_terminate(void) +void nrf_802154_rsch_prio_drop_hfclk_stop_terminate(void) { - nrf_802154_swi_hfclk_stop_terminate(); + swi_hfclk_stop_terminate(); +} + +void nrf_802154_rsch_prio_drop_swi_irq_handler(void) +{ + if (nrf_egu_event_check(NRF_802154_EGU_INSTANCE, HFCLK_STOP_EVENT)) + { + nrf_802154_clock_hfclk_stop(); + + nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, HFCLK_STOP_EVENT); + } } diff --git a/src/nrf_802154_procedures_duration.h b/src/nrf_802154_procedures_duration.h index 6cbc297..7a782a3 100644 --- a/src/nrf_802154_procedures_duration.h +++ b/src/nrf_802154_procedures_duration.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -63,6 +64,11 @@ A_TURNAROUND_TIME_SYMBOLS + \ IMM_ACK_SYMBOLS) +/**@brief Time (in microseconds) necessary to send the longest possible 802.15.4 frame */ +#define MAX_PHY_FRAME_TIME_US \ + PHY_US_TIME_FROM_SYMBOLS( \ + PHY_SHR_SYMBOLS + PHY_SYMBOLS_FROM_OCTETS(PHR_SIZE + MAX_PACKET_SIZE)) + __STATIC_INLINE uint16_t nrf_802154_tx_duration_get(uint8_t psdu_length, bool cca, bool ack_requested); diff --git a/src/nrf_802154_queue.c b/src/nrf_802154_queue.c new file mode 100644 index 0000000..521758e --- /dev/null +++ b/src/nrf_802154_queue.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Module implementing simple FIFO queue. + */ + +#include + +#include "nrf_802154_queue.h" + +static inline uint8_t increment_modulo(uint8_t v, uint8_t wrap_at_value) +{ + v++; + + if (v >= wrap_at_value) + { + v = 0U; + } + + return v; +} + +static inline void * idx2ptr(const nrf_802154_queue_t * p_queue, size_t idx) +{ + return ((uint8_t *)(p_queue->p_memory)) + idx * p_queue->item_size; +} + +void nrf_802154_queue_init(nrf_802154_queue_t * p_queue, + void * p_memory, + size_t memory_size, + size_t item_size) +{ + assert(p_queue != NULL); + assert(p_memory != NULL); + assert(item_size != 0U); + + /* Due uint8_t type of nrf_802154_queue_t::item_size */ + assert(item_size <= UINT8_MAX); + + size_t capacity = memory_size / item_size; + + /* Due simplified design, one entry in p_memory array is lost, + * see nrf_802154_queue_is_empty and nrf_802154_queue_is_full */ + assert(capacity >= 2U); + + /* Due uint8_t type of nrf_802154_queue_t::capacity */ + assert(capacity <= UINT8_MAX); + + p_queue->p_memory = p_memory; + p_queue->capacity = capacity; + p_queue->item_size = item_size; + p_queue->wridx = 0U; + p_queue->rdidx = 0U; +} + +void * nrf_802154_queue_push_begin(const nrf_802154_queue_t * p_queue) +{ + return idx2ptr(p_queue, p_queue->wridx); +} + +void nrf_802154_queue_push_commit(nrf_802154_queue_t * p_queue) +{ + p_queue->wridx = increment_modulo(p_queue->wridx, p_queue->capacity); +} + +void * nrf_802154_queue_pop_begin(const nrf_802154_queue_t * p_queue) +{ + return idx2ptr(p_queue, p_queue->rdidx); +} + +void nrf_802154_queue_pop_commit(nrf_802154_queue_t * p_queue) +{ + p_queue->rdidx = increment_modulo(p_queue->rdidx, p_queue->capacity); +} + +bool nrf_802154_queue_is_full(const nrf_802154_queue_t * p_queue) +{ + size_t wridx; + + wridx = increment_modulo(p_queue->wridx, p_queue->capacity); + + return (p_queue->rdidx == wridx); +} diff --git a/src/nrf_802154_queue.h b/src/nrf_802154_queue.h new file mode 100644 index 0000000..89e273d --- /dev/null +++ b/src/nrf_802154_queue.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Module implementing simple FIFO queue. + */ + +#ifndef NRF_802154_QUEUE_H__ +#define NRF_802154_QUEUE_H__ + +#include +#include +#include + +/**@brief Type representing a FIFO queue. */ +typedef struct +{ + /**@brief Pointer to items memory of the queue. + * @details Memory pointed by this pointer has size @c item_size * @c capacity. */ + void * p_memory; + + /**@brief Size of an item in the queue. */ + uint8_t item_size; + + /**@brief Maximum number of items that can be stored in the memory of the queue */ + uint8_t capacity; + + /**@brief Index in the items memory of the queue where next item is written. */ + volatile uint8_t wridx; + + /**@brief Index in the items memory of the queue where next item is read. */ + volatile uint8_t rdidx; +} nrf_802154_queue_t; + +/**@brief Initializes a queue. + * + * @param[in] p_queue Pointer to the queue instance to be initialized. Must not be NULL. + * @param[in] p_memory Pointer to a memory that will be used to store items of the queue. + * Must not be NULL. + * @param[in] memory_size Size of the memory pointed by @p p_memory. + * This parameter must be no less than 2 * @p item_size + * @param[in] item_size Size of an item of the queue. Must not be 0. + */ +void nrf_802154_queue_init(nrf_802154_queue_t * p_queue, + void * p_memory, + size_t memory_size, + size_t item_size); + +/**@brief Returns pointer to the next item to be written to the queue. + * + * This function is to be used when writing data to the queue directly (no copy). + * Returned pointer is valid when the queue is not full (@ref nrf_802154_queue_is_full returned false). + * To write an item to the queue perform following. + * @code + * if (!nrf_802154_queue_is_full(&queue)) + * { + * my_item_t * p_item = (my_item_t *)nrf_802154_queue_push_begin(&queue); + * ... p_item is now direct pointer into memory of the queue, fill all data at p_item pointer + * p_item->some_field = some_value; + * ... fill all data at p_item pointer + * nrf_802154_queue_push_commit(&queue) + * } + * @endcode + * + * To ensure thread-safety external locking is required. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return Pointer to the next item to be written. + */ +void * nrf_802154_queue_push_begin(const nrf_802154_queue_t * p_queue); + +/**@brief Increments write pointer of the queue. + * + * @param[in] p_queue Pointer to the queue instance. + */ +void nrf_802154_queue_push_commit(nrf_802154_queue_t * p_queue); + +/**@brief Returns pointer to the next item to be read from the queue. + * + * This function is to be used when reading data from the queue directly (no copy). + * Returned pointer is valid when the queue is not empty (@ref nrf_802154_queue_is_empty returned false). + * To ensure thread-safety external locking is required. + * + * To read an item from the queue perform following. + * @code + * if (!nrf_802154_queue_is_empty(&queue)) + * { + * my_item_t * p_item = (my_item_t *)nrf_802154_queue_pop_begin(&queue); + * ... read & process data pointed by p_item + * nrf_802154_queue_pop_commit(&queue) + * } + * @endcode + * + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return Pointer to the next item to be written. + */ +void * nrf_802154_queue_pop_begin(const nrf_802154_queue_t * p_queue); + +/**@brief Increments read pointer of the queue. + * + * @param[in] p_queue Pointer to the queue instance. + */ +void nrf_802154_queue_pop_commit(nrf_802154_queue_t * p_queue); + +/**@brief Checks if the queue is empty. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @retval true When the queue is empty + * @retval false When the queue is not empty. + */ +static inline bool nrf_802154_queue_is_empty(const nrf_802154_queue_t * p_queue) +{ + return (p_queue->wridx == p_queue->rdidx); +} + +/**@brief Checks if the queue is full. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @retval true When the queue is full. + * @retval false When the queue is not full. + */ +bool nrf_802154_queue_is_full(const nrf_802154_queue_t * p_queue); + +#endif /* NRF_802154_QUEUE_H__ */ diff --git a/src/nrf_802154_request.h b/src/nrf_802154_request.h index 7f2f5a9..70ea1b7 100644 --- a/src/nrf_802154_request.h +++ b/src/nrf_802154_request.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_REQUEST_H__ @@ -133,6 +134,17 @@ bool nrf_802154_request_cca(nrf_802154_term_t term_lvl); */ bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl); +/** + * @brief Requests entering the @ref RADIO_STATE_MODULATED_CARRIER state. + * + * @param[in] term_lvl Termination level of this request. Selects procedures to abort. + * + * @retval true The driver will enter the modulated carrier state. + * @retval false The driver cannot enter the modulated carrier state due to an ongoing operation. + */ +bool nrf_802154_request_modulated_carrier(nrf_802154_term_t term_lvl, + const uint8_t * p_data); + /** * @brief Requests the driver to free the given buffer. * @@ -140,6 +152,11 @@ bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl); */ bool nrf_802154_request_buffer_free(uint8_t * p_data); +/** + * @brief Requests the driver to update the antenna used. + */ +bool nrf_802154_request_antenna_update(void); + /** * @brief Requests the driver to update the channel number used by the RADIO peripheral. */ diff --git a/src/nrf_802154_request_direct.c b/src/nrf_802154_request_direct.c index f320a93..5e4305a 100644 --- a/src/nrf_802154_request_direct.c +++ b/src/nrf_802154_request_direct.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -40,13 +41,20 @@ #include #include "nrf_802154_core.h" -#include "nrf_radio.h" +#include "hal/nrf_radio.h" + +#define REQUEST_FUNCTION_PARMS(func_core, ...) \ + bool result; \ + \ + result = func_core(__VA_ARGS__); \ + \ + return result; -#define REQUEST_FUNCTION(func_core, ...) \ - bool result; \ - \ - result = func_core(__VA_ARGS__); \ - \ +#define REQUEST_FUNCTION(func_core) \ + bool result; \ + \ + result = func_core(); \ + \ return result; void nrf_802154_request_init(void) @@ -56,7 +64,7 @@ void nrf_802154_request_init(void) bool nrf_802154_request_sleep(nrf_802154_term_t term_lvl) { - REQUEST_FUNCTION(nrf_802154_core_sleep, term_lvl) + REQUEST_FUNCTION_PARMS(nrf_802154_core_sleep, term_lvl) } bool nrf_802154_request_receive(nrf_802154_term_t term_lvl, @@ -64,7 +72,11 @@ bool nrf_802154_request_receive(nrf_802154_term_t term_lvl, nrf_802154_notification_func_t notify_function, bool notify_abort) { - REQUEST_FUNCTION(nrf_802154_core_receive, term_lvl, req_orig, notify_function, notify_abort) + REQUEST_FUNCTION_PARMS(nrf_802154_core_receive, + term_lvl, + req_orig, + notify_function, + notify_abort) } bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl, @@ -74,33 +86,44 @@ bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl, bool immediate, nrf_802154_notification_func_t notify_function) { - REQUEST_FUNCTION(nrf_802154_core_transmit, - term_lvl, - req_orig, - p_data, - cca, - immediate, - notify_function) + REQUEST_FUNCTION_PARMS(nrf_802154_core_transmit, + term_lvl, + req_orig, + p_data, + cca, + immediate, + notify_function) } bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_us) { - REQUEST_FUNCTION(nrf_802154_core_energy_detection, term_lvl, time_us) + REQUEST_FUNCTION_PARMS(nrf_802154_core_energy_detection, term_lvl, time_us) } bool nrf_802154_request_cca(nrf_802154_term_t term_lvl) { - REQUEST_FUNCTION(nrf_802154_core_cca, term_lvl) + REQUEST_FUNCTION_PARMS(nrf_802154_core_cca, term_lvl) } bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl) { - REQUEST_FUNCTION(nrf_802154_core_continuous_carrier, term_lvl) + REQUEST_FUNCTION_PARMS(nrf_802154_core_continuous_carrier, term_lvl) +} + +bool nrf_802154_request_modulated_carrier(nrf_802154_term_t term_lvl, + const uint8_t * p_data) +{ + REQUEST_FUNCTION_PARMS(nrf_802154_core_modulated_carrier, term_lvl, p_data) } bool nrf_802154_request_buffer_free(uint8_t * p_data) { - REQUEST_FUNCTION(nrf_802154_core_notify_buffer_free, p_data) + REQUEST_FUNCTION_PARMS(nrf_802154_core_notify_buffer_free, p_data) +} + +bool nrf_802154_request_antenna_update(void) +{ + REQUEST_FUNCTION(nrf_802154_core_antenna_update) } bool nrf_802154_request_channel_update(void) @@ -120,5 +143,5 @@ bool nrf_802154_request_rssi_measure(void) bool nrf_802154_request_rssi_measurement_get(int8_t * p_rssi) { - REQUEST_FUNCTION(nrf_802154_core_last_rssi_measurement_get, p_rssi) + REQUEST_FUNCTION_PARMS(nrf_802154_core_last_rssi_measurement_get, p_rssi) } diff --git a/src/nrf_802154_request_swi.c b/src/nrf_802154_request_swi.c index ddc861e..3c44f56 100644 --- a/src/nrf_802154_request_swi.c +++ b/src/nrf_802154_request_swi.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -45,18 +46,182 @@ #include "nrf_802154_critical_section.h" #include "nrf_802154_debug.h" #include "nrf_802154_peripherals.h" +#include "nrf_802154_queue.h" #include "nrf_802154_rx_buffer.h" #include "nrf_802154_swi.h" #include "nrf_802154_utils.h" -#include "nrf_radio.h" +#include "hal/nrf_radio.h" +#include "hal/nrf_egu.h" #include "platform/irq/nrf_802154_irq.h" #include +/** Size of requests queue. + * + * Two is minimal queue size. It is not expected in current implementation to queue a few requests. + */ +#define REQ_QUEUE_SIZE 2 + +#define REQ_INT NRF_EGU_INT_TRIGGERED2 ///< Label of request interrupt. +#define REQ_TASK NRF_EGU_TASK_TRIGGER2 ///< Label of request task. +#define REQ_EVENT NRF_EGU_EVENT_TRIGGERED2 ///< Label of request event. + +/// Type of requests in request queue. +typedef enum +{ + REQ_TYPE_SLEEP, + REQ_TYPE_RECEIVE, + REQ_TYPE_TRANSMIT, + REQ_TYPE_ENERGY_DETECTION, + REQ_TYPE_CCA, + REQ_TYPE_CONTINUOUS_CARRIER, + REQ_TYPE_MODULATED_CARRIER, + REQ_TYPE_BUFFER_FREE, + REQ_TYPE_CHANNEL_UPDATE, + REQ_TYPE_CCA_CFG_UPDATE, + REQ_TYPE_RSSI_MEASURE, + REQ_TYPE_RSSI_GET, + REQ_TYPE_ANTENNA_UPDATE, +} nrf_802154_req_type_t; + +/// Request data in request queue. +typedef struct +{ + nrf_802154_req_type_t type; ///< Type of the request. + + union + { + struct + { + nrf_802154_term_t term_lvl; ///< Request priority. + bool * p_result; ///< Sleep request result. + } sleep; ///< Sleep request details. + + struct + { + nrf_802154_notification_func_t notif_func; ///< Error notified in case of success. + nrf_802154_term_t term_lvl; ///< Request priority. + req_originator_t req_orig; ///< Request originator. + bool notif_abort; ///< If function termination should be notified. + bool * p_result; ///< Receive request result. + } receive; ///< Receive request details. + + struct + { + nrf_802154_notification_func_t notif_func; ///< Error notified in case of success. + nrf_802154_term_t term_lvl; ///< Request priority. + req_originator_t req_orig; ///< Request originator. + const uint8_t * p_data; ///< Pointer to a buffer containing PHR and PSDU of the frame to transmit. + bool cca; ///< If CCA was requested prior to transmission. + bool immediate; ///< If TX procedure must be performed immediately. + bool * p_result; ///< Transmit request result. + } transmit; ///< Transmit request details. + + struct + { + nrf_802154_term_t term_lvl; ///< Request priority. + bool * p_result; ///< Energy detection request result. + uint32_t time_us; ///< Requested time of energy detection procedure. + } energy_detection; ///< Energy detection request details. + + struct + { + nrf_802154_term_t term_lvl; ///< Request priority. + bool * p_result; ///< CCA request result. + } cca; ///< CCA request details. + + struct + { + nrf_802154_term_t term_lvl; ///< Request priority. + bool * p_result; ///< Continuous carrier request result. + } continuous_carrier; ///< Continuous carrier request details. + + struct + { + nrf_802154_term_t term_lvl; ///< Request priority. + const uint8_t * p_data; ///< Pointer to a buffer to modulate the carrier wave with. + bool * p_result; ///< Modulated carrier request result. + } modulated_carrier; ///< Modulated carrier request details. + + struct + { + uint8_t * p_data; ///< Pointer to receive buffer to free. + bool * p_result; ///< Buffer free request result. + } buffer_free; ///< Buffer free request details. + + struct + { + bool * p_result; ///< Channel update request result. + } channel_update; ///< Channel update request details. + + struct + { + bool * p_result; ///< CCA config update request result. + } cca_cfg_update; ///< CCA config update request details. + + struct + { + bool * p_result; ///< RSSI measurement request result. + } rssi_measure; ///< RSSI measurement request details. + + struct + { + int8_t * p_rssi; ///< RSSI measurement result. + bool * p_result; ///< RSSI measurement status. + } rssi_get; ///< Details of the getter that retrieves the RSSI measurement result. + + struct + { + bool * p_result; ///< Antenna update request result. + } antenna_update; ///< Antenna update request details. + } data; ///< Request data depending on its type. +} nrf_802154_req_data_t; + +/**@brief Instance of a requests queue */ +static nrf_802154_queue_t m_requests_queue; + +/**@brief Memory holding requests queue items */ +static nrf_802154_req_data_t m_requests_queue_memory[REQ_QUEUE_SIZE]; + +/**@brief State of the MCU critical section */ +static volatile nrf_802154_mcu_critical_state_t m_mcu_cs; + +/** + * Enter request block. + * + * This is a helper function used in all request functions to atomically + * find an empty slot in request queue and allow atomic slot update. + * + * @return Pointer to an empty slot in the request queue. + */ +static nrf_802154_req_data_t * req_enter(void) +{ + nrf_802154_mcu_critical_enter(m_mcu_cs); + + assert(!nrf_802154_queue_is_full(&m_requests_queue)); + + return (nrf_802154_req_data_t *)nrf_802154_queue_push_begin(&m_requests_queue); +} + +/** + * Exit request block. + * + * This is a helper function used in all request functions to end atomic slot update + * and trigger SWI to process the request from the slot. + */ +static void req_exit(void) +{ + nrf_802154_queue_push_commit(&m_requests_queue); + + nrf_egu_task_trigger(NRF_802154_EGU_INSTANCE, REQ_TASK); + + nrf_802154_mcu_critical_exit(m_mcu_cs); +} + /** Assert if SWI interrupt is disabled. */ static inline void assert_interrupt_status(void) { - assert(nrf_802154_irq_is_enabled(NRF_802154_SWI_IRQN)); + assert(nrf_802154_irq_is_enabled(NRF_802154_EGU_IRQN)); } #define REQUEST_FUNCTION(func_core, func_swi, ...) \ @@ -97,17 +262,281 @@ static inline void assert_interrupt_status(void) static bool active_vector_priority_is_high(void) { - return nrf_802154_critical_section_active_vector_priority_get() <= NRF_802154_SWI_PRIORITY; + return nrf_802154_critical_section_active_vector_priority_get() <= + nrf_802154_irq_priority_get(NRF_802154_EGU_IRQN); +} + +/** + * @brief Requests entering the @ref RADIO_STATE_SLEEP state from the SWI priority. + * + * @param[in] term_lvl Termination level of this request. Selects procedures to abort. + * @param[out] p_result Result of entering the sleep state. + */ +static void swi_sleep(nrf_802154_term_t term_lvl, bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_SLEEP; + p_slot->data.sleep.term_lvl = term_lvl; + p_slot->data.sleep.p_result = p_result; + + req_exit(); +} + +/** + * @brief Requests entering the @ref RADIO_STATE_RX state from the SWI priority. + * + * @param[in] term_lvl Termination level of this request. Selects procedures to abort. + * @param[in] req_orig Module that originates this request. + * @param[in] notify_function Function called to notify the status of the procedure. May be NULL. + * @param[in] notify_abort If abort notification should be triggered automatically. + * @param[out] p_result Result of entering the receive state. + */ +static void swi_receive(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + nrf_802154_notification_func_t notify_function, + bool notify_abort, + bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_RECEIVE; + p_slot->data.receive.term_lvl = term_lvl; + p_slot->data.receive.req_orig = req_orig; + p_slot->data.receive.notif_func = notify_function; + p_slot->data.receive.notif_abort = notify_abort; + p_slot->data.receive.p_result = p_result; + + req_exit(); +} + +/** + * @biref Requests entering the @ref RADIO_STATE_TX state from the SWI priority. + * + * @param[in] term_lvl Termination level of this request. Selects procedures to abort. + * @param[in] req_orig Module that originates this request. + * @param[in] p_data Pointer to a buffer that contains PHR and PSDU of the frame to be + * transmitted. + * @param[in] cca If the driver should perform the CCA procedure before transmission. + * @param[in] immediate If true, the driver schedules transmission immediately or never; + * if false, the transmission may be postponed until TX preconditions + * are met. + * @param[in] notify_function Function called to notify the status of this procedure instead of + * the default notification. If NULL, the default notification + * is used. + * @param[out] p_result Result of entering the transmit state. + */ +static void swi_transmit(nrf_802154_term_t term_lvl, + req_originator_t req_orig, + const uint8_t * p_data, + bool cca, + bool immediate, + nrf_802154_notification_func_t notify_function, + bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_TRANSMIT; + p_slot->data.transmit.term_lvl = term_lvl; + p_slot->data.transmit.req_orig = req_orig; + p_slot->data.transmit.p_data = p_data; + p_slot->data.transmit.cca = cca; + p_slot->data.transmit.immediate = immediate; + p_slot->data.transmit.notif_func = notify_function; + p_slot->data.transmit.p_result = p_result; + + req_exit(); +} + +/** + * @brief Requests entering the @ref RADIO_STATE_ED state from the SWI priority. + * + * @param[in] term_lvl Termination level of this request. Selects procedures to abort. + * @param[in] time_us Requested duration of the energy detection procedure. + * @param[out] p_result Result of entering the energy detection state. + */ +static void swi_energy_detection(nrf_802154_term_t term_lvl, + uint32_t time_us, + bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_ENERGY_DETECTION; + p_slot->data.energy_detection.term_lvl = term_lvl; + p_slot->data.energy_detection.time_us = time_us; + p_slot->data.energy_detection.p_result = p_result; + + req_exit(); +} + +/** + * @brief Requests entering the @ref RADIO_STATE_CCA state from the SWI priority. + * + * @param[in] term_lvl Termination level of this request. Selects procedures to abort. + * @param[out] p_result Result of entering the CCA state. + */ +static void swi_cca(nrf_802154_term_t term_lvl, bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_CCA; + p_slot->data.cca.term_lvl = term_lvl; + p_slot->data.cca.p_result = p_result; + + req_exit(); +} + +/** + * @brief Requests entering the @ref RADIO_STATE_CONTINUOUS_CARRIER state from the SWI priority. + * + * @param[in] term_lvl Termination level of this request. Selects procedures to abort. + * @param[out] p_result Result of entering the continuous carrier state. + */ +static void swi_continuous_carrier(nrf_802154_term_t term_lvl, bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_CONTINUOUS_CARRIER; + p_slot->data.continuous_carrier.term_lvl = term_lvl; + p_slot->data.continuous_carrier.p_result = p_result; + + req_exit(); +} + +/** + * @brief Requests entering the @ref RADIO_STATE_MODULATED_CARRIER state from the SWI priority. + * + * @param[in] term_lvl Termination level of this request. Selects procedures to abort. + * @param[in] p_data Pointer to the data buffer to modulate the carrier wave with. + * @param[out] p_result Result of entering the modulated carrier state. + */ +static void swi_modulated_carrier(nrf_802154_term_t term_lvl, + const uint8_t * p_data, + bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_MODULATED_CARRIER; + p_slot->data.modulated_carrier.term_lvl = term_lvl; + p_slot->data.modulated_carrier.p_data = p_data; + p_slot->data.modulated_carrier.p_result = p_result; + + req_exit(); +} + +/** + * @brief Notifies the core module that the given buffer is not used anymore and can be freed. + * + * @param[in] p_data Pointer to the buffer to be freed. + * @param[out] p_result Pointer where the result to be returned by + * nrf_802154_request_buffer_free should be written by the swi handler. + */ +static void swi_buffer_free(uint8_t * p_data, bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_BUFFER_FREE; + p_slot->data.buffer_free.p_data = p_data; + p_slot->data.buffer_free.p_result = p_result; + + req_exit(); +} + +/** + * @brief Notifies the core module that the next higher layer has requested an antenna change. + * + * @param[out] p_result Pointer where the result to be returned by + * nrf_802154_request_antenna_update should be written by the swi handler. + */ +static void swi_antenna_update(bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_ANTENNA_UPDATE; + p_slot->data.antenna_update.p_result = p_result; + + req_exit(); +} + +/** + * @brief Notifies the core module that the next higher layer has requested a channel change. + * + * @param[out] p_result Pointer where the result to be returned by + * nrf_802154_request_channel_update should be written by the swi handler. + */ +static void swi_channel_update(bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_CHANNEL_UPDATE; + p_slot->data.channel_update.p_result = p_result; + + req_exit(); +} + +/** + * @brief Notifies the core module that the next higher layer has requested a CCA configuration + * change. + * @param[out] p_result Pointer where the result to be returned by + * nrf_802154_request_cca_cfg_update should be written by the swi handler. + */ +static void swi_cca_cfg_update(bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_CCA_CFG_UPDATE; + p_slot->data.cca_cfg_update.p_result = p_result; + + req_exit(); +} + +/** + * @brief Notifies the core module that the next higher layer requested the RSSI measurement. + * + * @param[out] p_result Pointer where the result to be returned by + * nrf_802154_request_rssi_measure should be written by the swi handler. + */ +static void swi_rssi_measure(bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_RSSI_MEASURE; + p_slot->data.rssi_measure.p_result = p_result; + + req_exit(); +} + +/** + * @brief Gets the last RSSI measurement result from the core module. + * + * @param[out] p_rssi Pointer where RSSI measurement value will be stored. + * @param[out] p_result Pointer where the result to be returned by + * nrf_802154_request_rssi_measurement_get should be written by the swi handler. + */ +static void swi_rssi_measurement_get(int8_t * p_rssi, bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_RSSI_GET; + p_slot->data.rssi_get.p_rssi = p_rssi; + p_slot->data.rssi_get.p_result = p_result; + + req_exit(); } void nrf_802154_request_init(void) { + nrf_802154_queue_init(&m_requests_queue, m_requests_queue_memory, + sizeof(m_requests_queue_memory), sizeof(m_requests_queue_memory[0])); + + nrf_egu_int_enable(NRF_802154_EGU_INSTANCE, REQ_INT); + nrf_802154_swi_init(); } bool nrf_802154_request_sleep(nrf_802154_term_t term_lvl) { - REQUEST_FUNCTION(nrf_802154_core_sleep, nrf_802154_swi_sleep, term_lvl) + REQUEST_FUNCTION(nrf_802154_core_sleep, swi_sleep, term_lvl) } bool nrf_802154_request_receive(nrf_802154_term_t term_lvl, @@ -116,7 +545,7 @@ bool nrf_802154_request_receive(nrf_802154_term_t term_lvl, bool notify_abort) { REQUEST_FUNCTION(nrf_802154_core_receive, - nrf_802154_swi_receive, + swi_receive, term_lvl, req_orig, notify_function, @@ -131,7 +560,7 @@ bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl, nrf_802154_notification_func_t notify_function) { REQUEST_FUNCTION(nrf_802154_core_transmit, - nrf_802154_swi_transmit, + swi_transmit, term_lvl, req_orig, p_data, @@ -144,45 +573,159 @@ bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_us) { REQUEST_FUNCTION(nrf_802154_core_energy_detection, - nrf_802154_swi_energy_detection, + swi_energy_detection, term_lvl, time_us) } bool nrf_802154_request_cca(nrf_802154_term_t term_lvl) { - REQUEST_FUNCTION(nrf_802154_core_cca, nrf_802154_swi_cca, term_lvl) + REQUEST_FUNCTION(nrf_802154_core_cca, swi_cca, term_lvl) } bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl) { - REQUEST_FUNCTION(nrf_802154_core_continuous_carrier, nrf_802154_swi_continuous_carrier, + REQUEST_FUNCTION(nrf_802154_core_continuous_carrier, swi_continuous_carrier, term_lvl) } +bool nrf_802154_request_modulated_carrier(nrf_802154_term_t term_lvl, + const uint8_t * p_data) +{ + REQUEST_FUNCTION(nrf_802154_core_modulated_carrier, + swi_modulated_carrier, + term_lvl, + p_data) +} + bool nrf_802154_request_buffer_free(uint8_t * p_data) { - REQUEST_FUNCTION(nrf_802154_core_notify_buffer_free, nrf_802154_swi_buffer_free, p_data) + REQUEST_FUNCTION(nrf_802154_core_notify_buffer_free, swi_buffer_free, p_data) +} + +bool nrf_802154_request_antenna_update(void) +{ + REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_antenna_update, swi_antenna_update) } bool nrf_802154_request_channel_update(void) { - REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_channel_update, nrf_802154_swi_channel_update) + REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_channel_update, swi_channel_update) } bool nrf_802154_request_cca_cfg_update(void) { - REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_cca_cfg_update, nrf_802154_swi_cca_cfg_update) + REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_cca_cfg_update, swi_cca_cfg_update) } bool nrf_802154_request_rssi_measure(void) { - REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_rssi_measure, nrf_802154_swi_rssi_measure) + REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_rssi_measure, swi_rssi_measure) } bool nrf_802154_request_rssi_measurement_get(int8_t * p_rssi) { REQUEST_FUNCTION(nrf_802154_core_last_rssi_measurement_get, - nrf_802154_swi_rssi_measurement_get, + swi_rssi_measurement_get, p_rssi) } + +/**@brief Handles REQ_EVENT on NRF_802154_EGU_INSTANCE */ +static void irq_handler_req_event(void) +{ + while (!nrf_802154_queue_is_empty(&m_requests_queue)) + { + nrf_802154_req_data_t * p_slot = + (nrf_802154_req_data_t *)nrf_802154_queue_pop_begin(&m_requests_queue); + + switch (p_slot->type) + { + case REQ_TYPE_SLEEP: + *(p_slot->data.sleep.p_result) = + nrf_802154_core_sleep(p_slot->data.sleep.term_lvl); + break; + + case REQ_TYPE_RECEIVE: + *(p_slot->data.receive.p_result) = + nrf_802154_core_receive(p_slot->data.receive.term_lvl, + p_slot->data.receive.req_orig, + p_slot->data.receive.notif_func, + p_slot->data.receive.notif_abort); + break; + + case REQ_TYPE_TRANSMIT: + *(p_slot->data.transmit.p_result) = + nrf_802154_core_transmit(p_slot->data.transmit.term_lvl, + p_slot->data.transmit.req_orig, + p_slot->data.transmit.p_data, + p_slot->data.transmit.cca, + p_slot->data.transmit.immediate, + p_slot->data.transmit.notif_func); + break; + + case REQ_TYPE_ENERGY_DETECTION: + *(p_slot->data.energy_detection.p_result) = + nrf_802154_core_energy_detection( + p_slot->data.energy_detection.term_lvl, + p_slot->data.energy_detection.time_us); + break; + + case REQ_TYPE_CCA: + *(p_slot->data.cca.p_result) = nrf_802154_core_cca(p_slot->data.cca.term_lvl); + break; + + case REQ_TYPE_CONTINUOUS_CARRIER: + *(p_slot->data.continuous_carrier.p_result) = + nrf_802154_core_continuous_carrier( + p_slot->data.continuous_carrier.term_lvl); + break; + + case REQ_TYPE_MODULATED_CARRIER: + *(p_slot->data.modulated_carrier.p_result) = + nrf_802154_core_modulated_carrier(p_slot->data.modulated_carrier.term_lvl, + p_slot->data.modulated_carrier.p_data); + break; + + case REQ_TYPE_BUFFER_FREE: + *(p_slot->data.buffer_free.p_result) = + nrf_802154_core_notify_buffer_free(p_slot->data.buffer_free.p_data); + break; + + case REQ_TYPE_CHANNEL_UPDATE: + *(p_slot->data.channel_update.p_result) = nrf_802154_core_channel_update(); + break; + + case REQ_TYPE_CCA_CFG_UPDATE: + *(p_slot->data.cca_cfg_update.p_result) = nrf_802154_core_cca_cfg_update(); + break; + + case REQ_TYPE_RSSI_MEASURE: + *(p_slot->data.rssi_measure.p_result) = nrf_802154_core_rssi_measure(); + break; + + case REQ_TYPE_RSSI_GET: + *(p_slot->data.rssi_get.p_result) = + nrf_802154_core_last_rssi_measurement_get(p_slot->data.rssi_get.p_rssi); + break; + + case REQ_TYPE_ANTENNA_UPDATE: + *(p_slot->data.antenna_update.p_result) = nrf_802154_core_antenna_update(); + break; + + default: + assert(false); + } + + nrf_802154_queue_pop_commit(&m_requests_queue); + } +} + +void nrf_802154_request_swi_irq_handler(void) +{ + if (nrf_egu_event_check(NRF_802154_EGU_INSTANCE, REQ_EVENT)) + { + nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, REQ_EVENT); + + irq_handler_req_event(); + } +} diff --git a/src/nrf_802154_rssi.c b/src/nrf_802154_rssi.c index b9ed468..48a7c5b 100644 --- a/src/nrf_802154_rssi.c +++ b/src/nrf_802154_rssi.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/nrf_802154_rssi.h b/src/nrf_802154_rssi.h index 346795c..8e4be4c 100644 --- a/src/nrf_802154_rssi.h +++ b/src/nrf_802154_rssi.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_RSSI_H__ diff --git a/src/nrf_802154_rx_buffer.c b/src/nrf_802154_rx_buffer.c index ffc09b9..4ed20f4 100644 --- a/src/nrf_802154_rx_buffer.c +++ b/src/nrf_802154_rx_buffer.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/nrf_802154_rx_buffer.h b/src/nrf_802154_rx_buffer.h index 9ec93a0..05e37b8 100644 --- a/src/nrf_802154_rx_buffer.h +++ b/src/nrf_802154_rx_buffer.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/nrf_802154_stats.c b/src/nrf_802154_stats.c new file mode 100644 index 0000000..6dd160d --- /dev/null +++ b/src/nrf_802154_stats.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "nrf_802154.h" +#include "nrf_802154_stats.h" + +#define NUMBER_OF_STAT_COUNTERS (sizeof(nrf_802154_stat_counters_t) / sizeof(uint32_t)) +#define NUMBER_OF_STAT_TOTALS (sizeof(nrf_802154_stat_totals_t) / sizeof(uint64_t)) + +/**@brief Structure holding statistics about the Radio Driver behavior. */ +volatile nrf_802154_stats_t g_nrf_802154_stats; + +/**@brief Structure holding total times spent in certain states. */ +volatile nrf_802154_stat_totals_t g_nrf_802154_stat_totals; + +void nrf_802154_stats_get(nrf_802154_stats_t * p_stats) +{ + *p_stats = g_nrf_802154_stats; +} + +void nrf_802154_stat_counters_get(nrf_802154_stat_counters_t * p_stat_counters) +{ + *p_stat_counters = g_nrf_802154_stats.counters; +} + +void nrf_802154_stat_counters_subtract(const nrf_802154_stat_counters_t * p_stat_counters) +{ + volatile uint32_t * p_dst = (volatile uint32_t *)(&g_nrf_802154_stats.counters); + const uint32_t * p_src = (const uint32_t *)p_stat_counters; + + for (size_t i = 0; i < NUMBER_OF_STAT_COUNTERS; ++i) + { + nrf_802154_mcu_critical_state_t mcu_cs; + + nrf_802154_mcu_critical_enter(mcu_cs); + *p_dst -= *p_src; + nrf_802154_mcu_critical_exit(mcu_cs); + + p_dst++; + p_src++; + } +} + +void nrf_802154_stat_timestamps_get(nrf_802154_stat_timestamps_t * p_stat_timestamps) +{ + *p_stat_timestamps = g_nrf_802154_stats.timestamps; +} + +void nrf_802154_stat_counters_reset(void) +{ + volatile uint32_t * p_dst = (volatile uint32_t *)(&g_nrf_802154_stats.counters); + + for (size_t i = 0; i < NUMBER_OF_STAT_COUNTERS; ++i) + { + *(p_dst++) = 0U; + } +} + +void nrf_802154_stat_totals_get(nrf_802154_stat_totals_t * p_stat_totals) +{ + volatile uint64_t * p_dst = (volatile uint64_t *)p_stat_totals; + const uint64_t * p_src = (const uint64_t *)(&g_nrf_802154_stat_totals); + + nrf_802154_stat_totals_get_notify(); + + for (size_t i = 0; i < NUMBER_OF_STAT_TOTALS; ++i) + { + nrf_802154_mcu_critical_state_t mcu_cs; + + nrf_802154_mcu_critical_enter(mcu_cs); + *p_dst = *p_src; + nrf_802154_mcu_critical_exit(mcu_cs); + + p_dst++; + p_src++; + } +} + +__WEAK void nrf_802154_stat_totals_get_notify(void) +{ + /* Implementation here is intentionally empty. + * + * Implementation can be provided by other module to update g_nrf_802154_stat_totals + * to hold state until the moment of call. + */ +} diff --git a/src/nrf_802154_stats.h b/src/nrf_802154_stats.h new file mode 100644 index 0000000..685e820 --- /dev/null +++ b/src/nrf_802154_stats.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_802154_STATS_H_ +#define NRF_802154_STATS_H_ + +#include "nrf_802154_types.h" +#include "nrf_802154_utils.h" + +#if !defined(UNIT_TEST) +// Don't use directly. Use provided nrf_802154_stat_xxxx API macros. +extern volatile nrf_802154_stats_t g_nrf_802154_stats; + +extern volatile nrf_802154_stat_totals_t g_nrf_802154_stat_totals; + +/**@brief Increment one of the @ref nrf_802154_stat_counters_t fields. + * + * @param field_name Identifier of struct member to increment + */ +#define nrf_802154_stat_counter_increment(field_name) \ + do \ + { \ + nrf_802154_mcu_critical_state_t mcu_cs; \ + \ + nrf_802154_mcu_critical_enter(mcu_cs); \ + (g_nrf_802154_stats.counters.field_name)++; \ + nrf_802154_mcu_critical_exit(mcu_cs); \ + } \ + while (0) + +/**@brief Write one of the @ref nrf_802154_stat_timestamps_t fields. + * + * @param field_name Identifier of struct member to write + * @param value Value to write + */ +#define nrf_802154_stat_timestamp_write(field_name, value) \ + do \ + { \ + (g_nrf_802154_stats.timestamps.field_name) = (value); \ + } \ + while (0) + +/**@brief Read one of the @ref nrf_802154_stat_timestamps_t fields. */ +#define nrf_802154_stat_timestamp_read(field_name) \ + (g_nrf_802154_stats.timestamps.field_name) + +#define nrf_802154_stat_totals_increment(field_name, value) \ + do \ + { \ + nrf_802154_mcu_critical_state_t mcu_cs; \ + \ + nrf_802154_mcu_critical_enter(mcu_cs); \ + (g_nrf_802154_stat_totals.field_name) += (value); \ + nrf_802154_mcu_critical_exit(mcu_cs); \ + } \ + while (0) + +extern void nrf_802154_stat_totals_get_notify(void); + +#else // !defined(UNIT_TEST) + +#define nrf_802154_stat_counter_increment(field_name) \ + nrf_802154_stat_counter_increment_func(offsetof(nrf_802154_stat_counters_t, field_name)) + +#define nrf_802154_stat_timestamp_write(field_name, value) \ + nrf_802154_stat_timestamp_write_func(offsetof(nrf_802154_stat_timestamps_t, field_name), \ + (value)) + +#define nrf_802154_stat_timestamp_read(field_name) \ + nrf_802154_stat_timestamp_read_func(offsetof(nrf_802154_stat_timestamps_t, field_name)) + +// Functions for which mocks are generated. +void nrf_802154_stat_counter_increment_func(size_t field_offset); +void nrf_802154_stat_timestamp_write_func(size_t field_offset, uint32_t value); +uint32_t nrf_802154_stat_timestamp_read_func(size_t field_offset); + +#endif // !defined(UNIT_TEST) + +#endif /* NRF_802154_STATS_H_ */ diff --git a/src/nrf_802154_swi.c b/src/nrf_802154_swi.c index da5e880..7b90e0d 100644 --- a/src/nrf_802154_swi.c +++ b/src/nrf_802154_swi.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -40,835 +41,60 @@ #include #include +#include "compiler_abstraction.h" #include "nrf_802154.h" #include "nrf_802154_config.h" -#include "nrf_802154_core.h" #include "nrf_802154_peripherals.h" -#include "nrf_802154_rx_buffer.h" #include "nrf_802154_utils.h" -#include "nrf_egu.h" -#include "platform/clock/nrf_802154_clock.h" #include "platform/irq/nrf_802154_irq.h" -/** Size of notification queue. - * - * One slot for each receive buffer, one for transmission, one for busy channel and one for energy - * detection. - */ -#define NTF_QUEUE_SIZE (NRF_802154_RX_BUFFERS + 3) - -/** Size of requests queue. - * - * Two is minimal queue size. It is not expected in current implementation to queue a few requests. - */ -#define REQ_QUEUE_SIZE 2 - -#define SWI_EGU NRF_802154_SWI_EGU_INSTANCE ///< Label of SWI peripheral. -#define SWI_IRQn NRF_802154_SWI_IRQN ///< Symbol of SWI IRQ number. -#define SWI_IRQHandler NRF_802154_SWI_IRQ_HANDLER ///< Symbol of SWI IRQ handler. - -#define NTF_INT NRF_EGU_INT_TRIGGERED0 ///< Label of notification interrupt. -#define NTF_TASK NRF_EGU_TASK_TRIGGER0 ///< Label of notification task. -#define NTF_EVENT NRF_EGU_EVENT_TRIGGERED0 ///< Label of notification event. - -#define HFCLK_STOP_INT NRF_EGU_INT_TRIGGERED1 ///< Label of HFClk stop interrupt. -#define HFCLK_STOP_TASK NRF_EGU_TASK_TRIGGER1 ///< Label of HFClk stop task. -#define HFCLK_STOP_EVENT NRF_EGU_EVENT_TRIGGERED1 ///< Label of HFClk stop event. - -#define REQ_INT NRF_EGU_INT_TRIGGERED2 ///< Label of request interrupt. -#define REQ_TASK NRF_EGU_TASK_TRIGGER2 ///< Label of request task. -#define REQ_EVENT NRF_EGU_EVENT_TRIGGERED2 ///< Label of request event. - -#define RAW_LENGTH_OFFSET 0 -#define RAW_PAYLOAD_OFFSET 1 - -/// Types of notifications in notification queue. -typedef enum -{ - NTF_TYPE_RECEIVED, ///< Frame received - NTF_TYPE_RECEIVE_FAILED, ///< Frame reception failed - NTF_TYPE_TRANSMITTED, ///< Frame transmitted - NTF_TYPE_TRANSMIT_FAILED, ///< Frame transmission failure - NTF_TYPE_ENERGY_DETECTED, ///< Energy detection procedure ended - NTF_TYPE_ENERGY_DETECTION_FAILED, ///< Energy detection procedure failed - NTF_TYPE_CCA, ///< CCA procedure ended - NTF_TYPE_CCA_FAILED, ///< CCA procedure failed -} nrf_802154_ntf_type_t; - -/// Notification data in the notification queue. -typedef struct -{ - nrf_802154_ntf_type_t type; ///< Notification type. - - union - { - struct - { - uint8_t * p_data; ///< Pointer to a buffer containing PHR and PSDU of the received frame. - int8_t power; ///< RSSI of received frame. - uint8_t lqi; ///< LQI of received frame. - } received; ///< Received frame details. - - struct - { - nrf_802154_rx_error_t error; ///< An error code that indicates reason of the failure. - } receive_failed; - - struct - { - const uint8_t * p_frame; ///< Pointer to frame that was transmitted. - uint8_t * p_data; ///< Pointer to a buffer containing PHR and PSDU of the received ACK or NULL. - int8_t power; ///< RSSI of received ACK or 0. - uint8_t lqi; ///< LQI of received ACK or 0. - } transmitted; ///< Transmitted frame details. - - struct - { - const uint8_t * p_frame; ///< Pointer to frame that was requested to be transmitted, but failed. - nrf_802154_tx_error_t error; ///< An error code that indicates reason of the failure. - } transmit_failed; - - struct - { - int8_t result; ///< Energy detection result. - } energy_detected; ///< Energy detection details. - - struct - { - nrf_802154_ed_error_t error; ///< An error code that indicates reason of the failure. - } energy_detection_failed; ///< Energy detection failure details. - - struct - { - bool result; ///< CCA result. - } cca; ///< CCA details. - - struct - { - nrf_802154_cca_error_t error; ///< An error code that indicates reason of the failure. - } cca_failed; ///< CCA failure details. - } data; ///< Notification data depending on it's type. -} nrf_802154_ntf_data_t; - -/// Type of requests in request queue. -typedef enum -{ - REQ_TYPE_SLEEP, - REQ_TYPE_RECEIVE, - REQ_TYPE_TRANSMIT, - REQ_TYPE_ENERGY_DETECTION, - REQ_TYPE_CCA, - REQ_TYPE_CONTINUOUS_CARRIER, - REQ_TYPE_BUFFER_FREE, - REQ_TYPE_CHANNEL_UPDATE, - REQ_TYPE_CCA_CFG_UPDATE, - REQ_TYPE_RSSI_MEASURE, - REQ_TYPE_RSSI_GET, -} nrf_802154_req_type_t; - -/// Request data in request queue. -typedef struct -{ - nrf_802154_req_type_t type; ///< Type of the request. - - union - { - struct - { - nrf_802154_term_t term_lvl; ///< Request priority. - bool * p_result; ///< Sleep request result. - } sleep; ///< Sleep request details. - - struct - { - nrf_802154_notification_func_t notif_func; ///< Error notified in case of success. - nrf_802154_term_t term_lvl; ///< Request priority. - req_originator_t req_orig; ///< Request originator. - bool notif_abort; ///< If function termination should be notified. - bool * p_result; ///< Receive request result. - } receive; ///< Receive request details. - - struct - { - nrf_802154_notification_func_t notif_func; ///< Error notified in case of success. - nrf_802154_term_t term_lvl; ///< Request priority. - req_originator_t req_orig; ///< Request originator. - const uint8_t * p_data; ///< Pointer to a buffer containing PHR and PSDU of the frame to transmit. - bool cca; ///< If CCA was requested prior to transmission. - bool immediate; ///< If TX procedure must be performed immediately. - bool * p_result; ///< Transmit request result. - } transmit; ///< Transmit request details. - - struct - { - nrf_802154_term_t term_lvl; ///< Request priority. - bool * p_result; ///< Energy detection request result. - uint32_t time_us; ///< Requested time of energy detection procedure. - } energy_detection; ///< Energy detection request details. - - struct - { - nrf_802154_term_t term_lvl; ///< Request priority. - bool * p_result; ///< CCA request result. - } cca; ///< CCA request details. - - struct - { - nrf_802154_term_t term_lvl; ///< Request priority. - bool * p_result; ///< Continuous carrier request result. - } continuous_carrier; ///< Continuous carrier request details. - - struct - { - uint8_t * p_data; ///< Pointer to receive buffer to free. - bool * p_result; ///< Buffer free request result. - } buffer_free; ///< Buffer free request details. - - struct - { - bool * p_result; ///< Channel update request result. - } channel_update; ///< Channel update request details. - - struct - { - bool * p_result; ///< CCA config update request result. - } cca_cfg_update; ///< CCA config update request details. - - struct - { - bool * p_result; ///< RSSI measurement request result. - } rssi_measure; ///< RSSI measurement request details. - - struct - { - int8_t * p_rssi; ///< RSSI measurement result. - bool * p_result; ///< RSSI measurement status. - } rssi_get; ///< Details of the getter that retrieves the RSSI measurement result. - } data; ///< Request data depending on its type. -} nrf_802154_req_data_t; - -static nrf_802154_ntf_data_t m_ntf_queue[NTF_QUEUE_SIZE]; ///< Notification queue. -static uint8_t m_ntf_r_ptr; ///< Notification queue read index. -static uint8_t m_ntf_w_ptr; ///< Notification queue write index. - -static nrf_802154_req_data_t m_req_queue[REQ_QUEUE_SIZE]; ///< Request queue. -static uint8_t m_req_r_ptr; ///< Request queue read index. -static uint8_t m_req_w_ptr; ///< Request queue write index. - -/** - * Increment given index for any queue. - * - * @param[inout] p_ptr Index to increment. - * @param[in] queue_size Number of elements in the queue. - */ -static void queue_ptr_increment(uint8_t * p_ptr, uint8_t queue_size) -{ - if (++(*p_ptr) >= queue_size) - { - *p_ptr = 0; - } -} - -/** - * Check if given queue is full. - * - * @param[in] r_ptr Read index associated with given queue. - * @param[in] w_ptr Write index associated with given queue. - * @param[in] queue_size Number of elements in the queue. - * - * @retval true Given queue is full. - * @retval false Given queue is not full. - */ -static bool queue_is_full(uint8_t r_ptr, uint8_t w_ptr, uint8_t queue_size) -{ - if (w_ptr == (r_ptr - 1)) - { - return true; - } - - if ((r_ptr == 0) && (w_ptr == queue_size - 1)) - { - return true; - } - - return false; -} - -/** - * Check if given queue is empty. - * - * @param[in] r_ptr Read index associated with given queue. - * @param[in] w_ptr Write index associated with given queue. - * - * @retval true Given queue is empty. - * @retval false Given queue is not empty. - */ -static bool queue_is_empty(uint8_t r_ptr, uint8_t w_ptr) -{ - return (r_ptr == w_ptr); -} - -/** - * Increment given index associated with notification queue. - * - * @param[inout] p_ptr Pointer to the index to increment. - */ -static void ntf_queue_ptr_increment(uint8_t * p_ptr) -{ - queue_ptr_increment(p_ptr, NTF_QUEUE_SIZE); -} - -/** - * Check if notification queue is full. - * - * @retval true Notification queue is full. - * @retval false Notification queue is not full. - */ -static bool ntf_queue_is_full(void) -{ - return queue_is_full(m_ntf_r_ptr, m_ntf_w_ptr, NTF_QUEUE_SIZE); -} - -/** - * Check if notification queue is empty. - * - * @retval true Notification queue is empty. - * @retval false Notification queue is not empty. - */ -static bool ntf_queue_is_empty(void) -{ - return queue_is_empty(m_ntf_r_ptr, m_ntf_w_ptr); -} - -/** - * Enter notify block. - * - * This is a helper function used in all notification functions to atomically - * find an empty slot in the notification queue and allow atomic slot update. - * - * @return Pointer to an empty slot in the notification queue. - */ -static nrf_802154_ntf_data_t * ntf_enter(void) -{ - __disable_irq(); - __DSB(); - __ISB(); - - assert(!ntf_queue_is_full()); - (void)ntf_queue_is_full(); - - return &m_ntf_queue[m_ntf_w_ptr]; -} - -/** - * Exit notify block. - * - * This is a helper function used in all notification functions to end atomic slot update - * and trigger SWI to process the notification from the slot. - */ -static void ntf_exit(void) -{ - ntf_queue_ptr_increment(&m_ntf_w_ptr); - - nrf_egu_task_trigger(SWI_EGU, NTF_TASK); - - __enable_irq(); -} - -/** - * Increment given index associated with request queue. - * - * @param[inout] p_ptr Pointer to the index to increment. - */ -static void req_queue_ptr_increment(uint8_t * p_ptr) -{ - queue_ptr_increment(p_ptr, REQ_QUEUE_SIZE); -} - -/** - * Check if request queue is full. - * - * @retval true Request queue is full. - * @retval false Request queue is not full. - */ -static bool req_queue_is_full(void) -{ - return queue_is_full(m_req_r_ptr, m_req_w_ptr, REQ_QUEUE_SIZE); -} - -/** - * Check if request queue is empty. - * - * @retval true Request queue is empty. - * @retval false Request queue is not empty. - */ -static bool req_queue_is_empty(void) -{ - return queue_is_empty(m_req_r_ptr, m_req_w_ptr); -} - -/** - * Enter request block. - * - * This is a helper function used in all request functions to atomically - * find an empty slot in request queue and allow atomic slot update. - * - * @return Pointer to an empty slot in the request queue. - */ -static nrf_802154_req_data_t * req_enter(void) -{ - __disable_irq(); - __DSB(); - __ISB(); - - assert(!req_queue_is_full()); - (void)req_queue_is_full(); - - return &m_req_queue[m_req_w_ptr]; -} - -/** - * Exit request block. - * - * This is a helper function used in all request functions to end atomic slot update - * and trigger SWI to process the request from the slot. - */ -static void req_exit(void) -{ - req_queue_ptr_increment(&m_req_w_ptr); - - nrf_egu_task_trigger(SWI_EGU, REQ_TASK); - - __enable_irq(); - __DSB(); - __ISB(); -} - -void nrf_802154_swi_notify_received(uint8_t * p_data, int8_t power, uint8_t lqi) -{ - nrf_802154_ntf_data_t * p_slot = ntf_enter(); - - p_slot->type = NTF_TYPE_RECEIVED; - p_slot->data.received.p_data = p_data; - p_slot->data.received.power = power; - p_slot->data.received.lqi = lqi; - - ntf_exit(); -} - -void nrf_802154_swi_notify_receive_failed(nrf_802154_rx_error_t error) -{ - nrf_802154_ntf_data_t * p_slot = ntf_enter(); - - p_slot->type = NTF_TYPE_RECEIVE_FAILED; - p_slot->data.receive_failed.error = error; - - ntf_exit(); -} - -void nrf_802154_swi_notify_transmitted(const uint8_t * p_frame, - uint8_t * p_data, - int8_t power, - uint8_t lqi) -{ - nrf_802154_ntf_data_t * p_slot = ntf_enter(); - - p_slot->type = NTF_TYPE_TRANSMITTED; - p_slot->data.transmitted.p_frame = p_frame; - p_slot->data.transmitted.p_data = p_data; - p_slot->data.transmitted.power = power; - p_slot->data.transmitted.lqi = lqi; - - ntf_exit(); -} - -void nrf_802154_swi_notify_transmit_failed(const uint8_t * p_frame, nrf_802154_tx_error_t error) -{ - nrf_802154_ntf_data_t * p_slot = ntf_enter(); - - p_slot->type = NTF_TYPE_TRANSMIT_FAILED; - p_slot->data.transmit_failed.p_frame = p_frame; - p_slot->data.transmit_failed.error = error; - - ntf_exit(); -} - -void nrf_802154_swi_notify_energy_detected(uint8_t result) -{ - nrf_802154_ntf_data_t * p_slot = ntf_enter(); - - p_slot->type = NTF_TYPE_ENERGY_DETECTED; - p_slot->data.energy_detected.result = result; - - ntf_exit(); -} - -void nrf_802154_swi_notify_energy_detection_failed(nrf_802154_ed_error_t error) -{ - nrf_802154_ntf_data_t * p_slot = ntf_enter(); - - p_slot->type = NTF_TYPE_ENERGY_DETECTION_FAILED; - p_slot->data.energy_detection_failed.error = error; - - ntf_exit(); -} - -void nrf_802154_swi_notify_cca(bool channel_free) -{ - nrf_802154_ntf_data_t * p_slot = ntf_enter(); - - p_slot->type = NTF_TYPE_CCA; - p_slot->data.cca.result = channel_free; - - ntf_exit(); -} - -void nrf_802154_swi_notify_cca_failed(nrf_802154_cca_error_t error) -{ - nrf_802154_ntf_data_t * p_slot = ntf_enter(); - - p_slot->type = NTF_TYPE_CCA_FAILED; - p_slot->data.cca_failed.error = error; - - ntf_exit(); -} - -void nrf_802154_swi_hfclk_stop(void) -{ - assert(!nrf_egu_event_check(SWI_EGU, HFCLK_STOP_EVENT)); - - nrf_egu_task_trigger(SWI_EGU, HFCLK_STOP_TASK); -} - -void nrf_802154_swi_hfclk_stop_terminate(void) -{ - nrf_egu_event_clear(SWI_EGU, HFCLK_STOP_EVENT); -} - -void nrf_802154_swi_sleep(nrf_802154_term_t term_lvl, bool * p_result) -{ - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_SLEEP; - p_slot->data.sleep.term_lvl = term_lvl; - p_slot->data.sleep.p_result = p_result; - - req_exit(); -} - -void nrf_802154_swi_receive(nrf_802154_term_t term_lvl, - req_originator_t req_orig, - nrf_802154_notification_func_t notify_function, - bool notify_abort, - bool * p_result) -{ - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_RECEIVE; - p_slot->data.receive.term_lvl = term_lvl; - p_slot->data.receive.req_orig = req_orig; - p_slot->data.receive.notif_func = notify_function; - p_slot->data.receive.notif_abort = notify_abort; - p_slot->data.receive.p_result = p_result; - - req_exit(); -} - -void nrf_802154_swi_transmit(nrf_802154_term_t term_lvl, - req_originator_t req_orig, - const uint8_t * p_data, - bool cca, - bool immediate, - nrf_802154_notification_func_t notify_function, - bool * p_result) -{ - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_TRANSMIT; - p_slot->data.transmit.term_lvl = term_lvl; - p_slot->data.transmit.req_orig = req_orig; - p_slot->data.transmit.p_data = p_data; - p_slot->data.transmit.cca = cca; - p_slot->data.transmit.immediate = immediate; - p_slot->data.transmit.notif_func = notify_function; - p_slot->data.transmit.p_result = p_result; - - req_exit(); -} - -void nrf_802154_swi_energy_detection(nrf_802154_term_t term_lvl, - uint32_t time_us, - bool * p_result) -{ - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_ENERGY_DETECTION; - p_slot->data.energy_detection.term_lvl = term_lvl; - p_slot->data.energy_detection.time_us = time_us; - p_slot->data.energy_detection.p_result = p_result; - - req_exit(); -} - -void nrf_802154_swi_cca(nrf_802154_term_t term_lvl, bool * p_result) -{ - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_CCA; - p_slot->data.cca.term_lvl = term_lvl; - p_slot->data.cca.p_result = p_result; - - req_exit(); -} - -void nrf_802154_swi_continuous_carrier(nrf_802154_term_t term_lvl, bool * p_result) -{ - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_CONTINUOUS_CARRIER; - p_slot->data.continuous_carrier.term_lvl = term_lvl; - p_slot->data.continuous_carrier.p_result = p_result; - - req_exit(); -} - -void nrf_802154_swi_buffer_free(uint8_t * p_data, bool * p_result) -{ - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_BUFFER_FREE; - p_slot->data.buffer_free.p_data = p_data; - p_slot->data.buffer_free.p_result = p_result; - - req_exit(); -} +#if NRF_802154_INTERNAL_SWI_IRQ_HANDLING +/* SWI interrupt handling functionality is implemented directly by the chosen EGU IRQ handler. */ +#define SWI_IRQHandler NRF_802154_EGU_IRQ_HANDLER ///< Symbol of SWI IRQ handler. +#else +#define SWI_IRQHandler nrf_802154_swi_irq_handler ///< Symbol of SWI IRQ handler. +#endif -void nrf_802154_swi_channel_update(bool * p_result) +__WEAK void nrf_802154_trx_swi_irq_handler(void) { - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_CHANNEL_UPDATE; - p_slot->data.channel_update.p_result = p_result; - - req_exit(); + /* Implementation provided by other module if necessary */ } -void nrf_802154_swi_cca_cfg_update(bool * p_result) +__WEAK void nrf_802154_notification_swi_irq_handler(void) { - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_CCA_CFG_UPDATE; - p_slot->data.cca_cfg_update.p_result = p_result; - - req_exit(); + /* Implementation provided by other module if necessary */ } -void nrf_802154_swi_rssi_measure(bool * p_result) +__WEAK void nrf_802154_rsch_prio_drop_swi_irq_handler(void) { - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_RSSI_MEASURE; - p_slot->data.rssi_measure.p_result = p_result; - - req_exit(); + /* Implementation provided by other module if necessary */ } -void nrf_802154_swi_rssi_measurement_get(int8_t * p_rssi, bool * p_result) +__WEAK void nrf_802154_request_swi_irq_handler(void) { - nrf_802154_req_data_t * p_slot = req_enter(); - - p_slot->type = REQ_TYPE_RSSI_GET; - p_slot->data.rssi_get.p_rssi = p_rssi; - p_slot->data.rssi_get.p_result = p_result; - - req_exit(); + /* Implementation provided by other module if necessary */ } static void swi_irq_handler(void) { - if (nrf_egu_event_check(SWI_EGU, NTF_EVENT)) - { - nrf_egu_event_clear(SWI_EGU, NTF_EVENT); - - while (!ntf_queue_is_empty()) - { - nrf_802154_ntf_data_t * p_slot = &m_ntf_queue[m_ntf_r_ptr]; - - switch (p_slot->type) - { - case NTF_TYPE_RECEIVED: -#if NRF_802154_USE_RAW_API - nrf_802154_received_raw(p_slot->data.received.p_data, - p_slot->data.received.power, - p_slot->data.received.lqi); -#else // NRF_802154_USE_RAW_API - nrf_802154_received(p_slot->data.received.p_data + RAW_PAYLOAD_OFFSET, - p_slot->data.received.p_data[RAW_LENGTH_OFFSET], - p_slot->data.received.power, - p_slot->data.received.lqi); -#endif - break; - - case NTF_TYPE_RECEIVE_FAILED: - nrf_802154_receive_failed(p_slot->data.receive_failed.error); - break; - - case NTF_TYPE_TRANSMITTED: -#if NRF_802154_USE_RAW_API - nrf_802154_transmitted_raw(p_slot->data.transmitted.p_frame, - p_slot->data.transmitted.p_data, - p_slot->data.transmitted.power, - p_slot->data.transmitted.lqi); -#else // NRF_802154_USE_RAW_API - nrf_802154_transmitted(p_slot->data.transmitted.p_frame + RAW_PAYLOAD_OFFSET, - p_slot->data.transmitted.p_data == NULL ? NULL : - p_slot->data.transmitted.p_data + RAW_PAYLOAD_OFFSET, - p_slot->data.transmitted.p_data[RAW_LENGTH_OFFSET], - p_slot->data.transmitted.power, - p_slot->data.transmitted.lqi); -#endif - break; - - case NTF_TYPE_TRANSMIT_FAILED: -#if NRF_802154_USE_RAW_API - nrf_802154_transmit_failed(p_slot->data.transmit_failed.p_frame, - p_slot->data.transmit_failed.error); -#else // NRF_802154_USE_RAW_API - nrf_802154_transmit_failed( - p_slot->data.transmit_failed.p_frame + RAW_PAYLOAD_OFFSET, - p_slot->data.transmit_failed.error); -#endif - break; - - case NTF_TYPE_ENERGY_DETECTED: - nrf_802154_energy_detected(p_slot->data.energy_detected.result); - break; - - case NTF_TYPE_ENERGY_DETECTION_FAILED: - nrf_802154_energy_detection_failed( - p_slot->data.energy_detection_failed.error); - break; - - case NTF_TYPE_CCA: - nrf_802154_cca_done(p_slot->data.cca.result); - break; - - case NTF_TYPE_CCA_FAILED: - nrf_802154_cca_failed(p_slot->data.cca_failed.error); - break; - - default: - assert(false); - } - - ntf_queue_ptr_increment(&m_ntf_r_ptr); - } - } - - if (nrf_egu_event_check(SWI_EGU, HFCLK_STOP_EVENT)) - { - nrf_802154_clock_hfclk_stop(); - - nrf_egu_event_clear(SWI_EGU, HFCLK_STOP_EVENT); - } - - if (nrf_egu_event_check(SWI_EGU, REQ_EVENT)) - { - nrf_egu_event_clear(SWI_EGU, REQ_EVENT); - - while (!req_queue_is_empty()) - { - nrf_802154_req_data_t * p_slot = &m_req_queue[m_req_r_ptr]; - - switch (p_slot->type) - { - case REQ_TYPE_SLEEP: - *(p_slot->data.sleep.p_result) = - nrf_802154_core_sleep(p_slot->data.sleep.term_lvl); - break; - - case REQ_TYPE_RECEIVE: - *(p_slot->data.receive.p_result) = - nrf_802154_core_receive(p_slot->data.receive.term_lvl, - p_slot->data.receive.req_orig, - p_slot->data.receive.notif_func, - p_slot->data.receive.notif_abort); - break; - - case REQ_TYPE_TRANSMIT: - *(p_slot->data.transmit.p_result) = - nrf_802154_core_transmit(p_slot->data.transmit.term_lvl, - p_slot->data.transmit.req_orig, - p_slot->data.transmit.p_data, - p_slot->data.transmit.cca, - p_slot->data.transmit.immediate, - p_slot->data.transmit.notif_func); - break; - - case REQ_TYPE_ENERGY_DETECTION: - *(p_slot->data.energy_detection.p_result) = - nrf_802154_core_energy_detection( - p_slot->data.energy_detection.term_lvl, - p_slot->data.energy_detection.time_us); - break; - - case REQ_TYPE_CCA: - *(p_slot->data.cca.p_result) = nrf_802154_core_cca(p_slot->data.cca.term_lvl); - break; - - case REQ_TYPE_CONTINUOUS_CARRIER: - *(p_slot->data.continuous_carrier.p_result) = - nrf_802154_core_continuous_carrier( - p_slot->data.continuous_carrier.term_lvl); - break; - - case REQ_TYPE_BUFFER_FREE: - *(p_slot->data.buffer_free.p_result) = - nrf_802154_core_notify_buffer_free(p_slot->data.buffer_free.p_data); - break; - - case REQ_TYPE_CHANNEL_UPDATE: - *(p_slot->data.channel_update.p_result) = nrf_802154_core_channel_update(); - break; - - case REQ_TYPE_CCA_CFG_UPDATE: - *(p_slot->data.cca_cfg_update.p_result) = nrf_802154_core_cca_cfg_update(); - break; - - case REQ_TYPE_RSSI_MEASURE: - *(p_slot->data.rssi_measure.p_result) = nrf_802154_core_rssi_measure(); - break; - - case REQ_TYPE_RSSI_GET: - *(p_slot->data.rssi_get.p_result) = - nrf_802154_core_last_rssi_measurement_get(p_slot->data.rssi_get.p_rssi); - break; - - default: - assert(false); - } - - req_queue_ptr_increment(&m_req_r_ptr); - } - } + nrf_802154_trx_swi_irq_handler(); + nrf_802154_notification_swi_irq_handler(); + nrf_802154_rsch_prio_drop_swi_irq_handler(); + nrf_802154_request_swi_irq_handler(); } void nrf_802154_swi_init(void) { - m_ntf_r_ptr = 0; - m_ntf_w_ptr = 0; - - nrf_egu_int_enable(SWI_EGU, NTF_INT | HFCLK_STOP_INT | REQ_INT); - #if !NRF_802154_IRQ_PRIORITY_ALLOWED(NRF_802154_SWI_PRIORITY) #error NRF_802154_SWI_PRIORITY value out of the allowed range. #endif + static bool initialized = false; if (!initialized) { - nrf_802154_irq_init(SWI_IRQn, NRF_802154_SWI_PRIORITY, swi_irq_handler); - nrf_802154_irq_enable(SWI_IRQn); + nrf_802154_irq_init(NRF_802154_EGU_IRQN, NRF_802154_SWI_PRIORITY, swi_irq_handler); + nrf_802154_irq_enable(NRF_802154_EGU_IRQN); initialized = true; } } diff --git a/src/nrf_802154_swi.h b/src/nrf_802154_swi.h index e96f925..e338b55 100644 --- a/src/nrf_802154_swi.h +++ b/src/nrf_802154_swi.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_SWI_H__ @@ -34,10 +35,6 @@ #include #include -#include "nrf_802154.h" -#include "nrf_802154_const.h" -#include "nrf_802154_notification.h" - #ifdef __cplusplus extern "C" { #endif @@ -54,204 +51,6 @@ extern "C" { */ void nrf_802154_swi_init(void); -/** - * @brief Notifies the next higher layer that a frame was received. - * - * The notification is triggered from the SWI priority level. - * - * @param[in] p_data Pointer to a buffer that contains PHR and PSDU of the received frame. - * @param[in] power RSSI measured during the frame reception. - * @param[in] lqi LQI that indicates the measured link quality during the frame reception. - */ -void nrf_802154_swi_notify_received(uint8_t * p_data, int8_t power, uint8_t lqi); - -/** - * @brief Notifies the next higher layer that the reception of a frame failed. - * - * @param[in] error Error code that indicates reason of the failure. - */ -void nrf_802154_swi_notify_receive_failed(nrf_802154_rx_error_t error); - -/** - * @brief Notifies the next higher layer that a frame was transmitted - * - * The notification is triggered from the SWI priority level. - * - * @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the transmitted frame. - * @param[in] p_ack Pointer to a buffer that contains PHR and PSDU of ACK frame. NULL if ACK was - * not requested. - * @param[in] power RSSI of the received frame, or 0 if ACK was not requested. - * @param[in] lqi LQI of the received frame, or 0 if ACK was not requested. - */ -void nrf_802154_swi_notify_transmitted(const uint8_t * p_frame, - uint8_t * p_data, - int8_t power, - uint8_t lqi); - -/** - * @brief Notifies the next higher layer that a frame was not transmitted from the SWI priority - * level. - * - * @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame that failed - * the transmission. - * @param[in] error Reason of the transmission failure. - */ -void nrf_802154_swi_notify_transmit_failed(const uint8_t * p_frame, nrf_802154_tx_error_t error); - -/** - * @brief Notifies the next higher layer that the energy detection procedure ended from - * the SWI priority level. - * - * @param[in] result Detected energy level. - */ -void nrf_802154_swi_notify_energy_detected(uint8_t result); - -/** - * @brief Notifies the next higher layer that the energy detection procedure failed from - * the SWI priority level. - * - * @param[in] error Reason of the energy detection failure. - */ -void nrf_802154_swi_notify_energy_detection_failed(nrf_802154_ed_error_t error); - -/** - * @brief Notifies the next higher layer that the Clear Channel Assessment (CCA) procedure ended. - * - * The notification is triggered from the SWI priority level. - * - * @param[in] channel_free If a free channel was detected. - */ -void nrf_802154_swi_notify_cca(bool channel_free); - -/** - * @brief Notifies the next higher layer that the Clear Channel Assessment (CCA) procedure failed. - * - * The notification is triggered from the SWI priority level. - * - * @param[in] error Reason of the CCA failure. - */ -void nrf_802154_swi_notify_cca_failed(nrf_802154_cca_error_t error); - -/** - * @brief Requests a stop of the HF clock. - * - * The notification is triggered from the SWI priority level. - * - * @note This function is to be called through notification module to prevent calling it from - * the arbiter context. - */ -void nrf_802154_swi_hfclk_stop(void); - -/** - * @brief Terminates the stopping of the HF clock. - * - * @note This function terminates the stopping of the HF clock only if it has not been performed - * yet. - */ -void nrf_802154_swi_hfclk_stop_terminate(void); - -/** - * @brief Requests entering the @ref RADIO_STATE_SLEEP state from the SWI priority. - * - * @param[in] term_lvl Termination level of this request. Selects procedures to abort. - * @param[out] p_result Result of entering the sleep state. - */ -void nrf_802154_swi_sleep(nrf_802154_term_t term_lvl, bool * p_result); - -/** - * @brief Requests entering the @ref RADIO_STATE_RX state from the SWI priority. - * - * @param[in] term_lvl Termination level of this request. Selects procedures to abort. - * @param[in] req_orig Module that originates this request. - * @param[in] notify_function Function called to notify the status of the procedure. May be NULL. - * @param[in] notify_abort If abort notification should be triggered automatically. - * @param[out] p_result Result of entering the receive state. - */ -void nrf_802154_swi_receive(nrf_802154_term_t term_lvl, - req_originator_t req_orig, - nrf_802154_notification_func_t notify_function, - bool notify_abort, - bool * p_result); - -/** - * @biref Requests entering the @ref RADIO_STATE_TX state from the SWI priority. - * - * @param[in] term_lvl Termination level of this request. Selects procedures to abort. - * @param[in] req_orig Module that originates this request. - * @param[in] p_data Pointer to a buffer that contains PHR and PSDU of the frame to be - * transmitted. - * @param[in] cca If the driver should perform the CCA procedure before transmission. - * @param[in] immediate If true, the driver schedules transmission immediately or never; - * if false, the transmission may be postponed until TX preconditions - * are met. - * @param[in] notify_function Function called to notify the status of this procedure instead of - * the default notification. If NULL, the default notification - * is used. - * @param[out] p_result Result of entering the transmit state. - */ -void nrf_802154_swi_transmit(nrf_802154_term_t term_lvl, - req_originator_t req_orig, - const uint8_t * p_data, - bool cca, - bool immediate, - nrf_802154_notification_func_t notify_function, - bool * p_result); - -/** - * @brief Requests entering the @ref RADIO_STATE_ED state from the SWI priority. - * - * @param[in] term_lvl Termination level of this request. Selects procedures to abort. - * @param[in] time_us Requested duration of the energy detection procedure. - * @param[out] p_result Result of entering the energy detection state. - */ -void nrf_802154_swi_energy_detection(nrf_802154_term_t term_lvl, - uint32_t time_us, - bool * p_result); - -/** - * @brief Requests entering the @ref RADIO_STATE_CCA state from the SWI priority. - * - * @param[in] term_lvl Termination level of this request. Selects procedures to abort. - * @param[out] p_result Result of entering the CCA state. - */ -void nrf_802154_swi_cca(nrf_802154_term_t term_lvl, bool * p_result); - -/** - * @brief Requests entering the @ref RADIO_STATE_CONTINUOUS_CARRIER state from the SWI priority. - * - * @param[in] term_lvl Termination level of this request. Selects procedures to abort. - * @param[out] p_result Result of entering the continuous carrier state. - */ -void nrf_802154_swi_continuous_carrier(nrf_802154_term_t term_lvl, bool * p_result); - -/** - * @brief Notifies the core module that the given buffer is not used anymore and can be freed. - * - * @param[in] p_data Pointer to the buffer to be freed. - */ -void nrf_802154_swi_buffer_free(uint8_t * p_data, bool * p_result); - -/** - * @brief Notifies the core module that the next higher layer has requested a channel change. - */ -void nrf_802154_swi_channel_update(bool * p_result); - -/** - * @brief Notifies the core module that the next higher layer has requested a CCA configuration - * change. - */ -void nrf_802154_swi_cca_cfg_update(bool * p_result); - -/** - * @brief Notifies the core module that the next higher layer requested the RSSI measurement. - */ -void nrf_802154_swi_rssi_measure(bool * p_result); - -/** - * @brief Gets the last RSSI measurement result from the core module. - */ -void nrf_802154_swi_rssi_measurement_get(int8_t * p_rssi, bool * p_result); - /** *@} **/ diff --git a/src/nrf_802154_timer_coord.c b/src/nrf_802154_timer_coord.c deleted file mode 100644 index 0aaf598..0000000 --- a/src/nrf_802154_timer_coord.c +++ /dev/null @@ -1,268 +0,0 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements Timer Coordinator module. - * - */ - -#include "nrf_802154_timer_coord.h" - -#include -#include -#include - -#include "nrf_802154_config.h" -#include "nrf_802154_debug.h" -#include "nrf_802154_peripherals.h" -#include "platform/hp_timer/nrf_802154_hp_timer.h" -#include "platform/lp_timer/nrf_802154_lp_timer.h" - -#define DIV_ROUND_POSITIVE(n, d) (((n) + (d) / 2) / (d)) -#define DIV_ROUND_NEGATIVE(n, d) (((n) - (d) / 2) / (d)) -#define DIV_ROUND(n, d) ((((n) < 0) ^ ((d) < 0)) ? \ - DIV_ROUND_NEGATIVE(n, d) : \ - DIV_ROUND_POSITIVE(n, d)) - -#define TIME_BASE (1UL << 22) ///< Unit used to calculate PPTB (Point per Time Base). It is not equal million to speed up computations and increase precision. -#define FIRST_RESYNC_TIME TIME_BASE ///< Delay of the first resynchronization. The first resynchronization is needed to measure timers drift. -#define RESYNC_TIME (4 * TIME_BASE) ///< Delay of following resynchronizations. -#define EWMA_COEF (8) ///< Weight used in the EWMA algorithm. - -#define PPI_SYNC NRF_802154_PPI_RTC_COMPARE_TO_TIMER_CAPTURE -#define PPI_TIMESTAMP NRF_802154_PPI_TIMESTAMP_EVENT_TO_TIMER_CAPTURE -#define PPI_TIMESTAMP_GROUP NRF_802154_PPI_TIMESTAMP_GROUP - -#if NRF_802154_FRAME_TIMESTAMP_ENABLED -// Structure holding common timepoint from both timers. -typedef struct -{ - uint32_t lp_timer_time; ///< LP Timer time of common timepoint. - uint32_t hp_timer_time; ///< HP Timer time of common timepoint. -} common_timepoint_t; - -// Static variables. -static common_timepoint_t m_last_sync; ///< Common timepoint of last synchronization event. -static volatile bool m_synchronized; ///< If timers were synchronized since last start. -static bool m_drift_known; ///< If timer drift value is known. -static int32_t m_drift; ///< Drift of the HP timer relatively to the LP timer [PPTB]. - -void nrf_802154_timer_coord_init(void) -{ - uint32_t sync_event; - uint32_t sync_task; - - m_drift = 0; - m_drift_known = 0; - - nrf_802154_hp_timer_init(); - - sync_event = nrf_802154_lp_timer_sync_event_get(); - sync_task = nrf_802154_hp_timer_sync_task_get(); - - nrf_ppi_channel_endpoint_setup(PPI_SYNC, sync_event, sync_task); - nrf_ppi_channel_enable(PPI_SYNC); - - nrf_ppi_channel_include_in_group(PPI_TIMESTAMP, PPI_TIMESTAMP_GROUP); -} - -void nrf_802154_timer_coord_uninit(void) -{ - nrf_802154_hp_timer_deinit(); - - nrf_ppi_channel_disable(PPI_SYNC); - nrf_ppi_channel_endpoint_setup(PPI_SYNC, 0, 0); - - nrf_ppi_group_disable(PPI_TIMESTAMP_GROUP); - nrf_ppi_channel_and_fork_endpoint_setup(PPI_TIMESTAMP, 0, 0, 0); -} - -void nrf_802154_timer_coord_start(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TCOOR_START); - - m_synchronized = false; - nrf_802154_hp_timer_start(); - nrf_802154_hp_timer_sync_prepare(); - nrf_802154_lp_timer_sync_start_now(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TCOOR_START); -} - -void nrf_802154_timer_coord_stop(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TCOOR_STOP); - - nrf_802154_hp_timer_stop(); - nrf_802154_lp_timer_sync_stop(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TCOOR_STOP); -} - -void nrf_802154_timer_coord_timestamp_prepare(uint32_t event_addr) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TCOOR_TIMESTAMP_PREPARE); - - nrf_ppi_channel_and_fork_endpoint_setup(PPI_TIMESTAMP, - event_addr, - nrf_802154_hp_timer_timestamp_task_get(), - (uint32_t)nrf_ppi_task_group_disable_address_get( - PPI_TIMESTAMP_GROUP)); - - nrf_ppi_group_enable(PPI_TIMESTAMP_GROUP); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TCOOR_TIMESTAMP_PREPARE); -} - -bool nrf_802154_timer_coord_timestamp_get(uint32_t * p_timestamp) -{ - uint32_t hp_timestamp; - uint32_t hp_delta; - int32_t drift; - bool result = false; - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TCOOR_TIMESTAMP_GET); - assert(p_timestamp != NULL); - - if (m_synchronized) - { - hp_timestamp = nrf_802154_hp_timer_timestamp_get(); - hp_delta = hp_timestamp - m_last_sync.hp_timer_time; - drift = m_drift_known ? - (DIV_ROUND(((int64_t)m_drift * hp_delta), ((int64_t)TIME_BASE + m_drift))) : - 0; - *p_timestamp = m_last_sync.lp_timer_time + hp_delta - drift; - result = true; - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TCOOR_TIMESTAMP_GET); - return result; -} - -void nrf_802154_lp_timer_synchronized(void) -{ - common_timepoint_t sync_time; - uint32_t lp_delta; - uint32_t hp_delta; - int32_t timers_diff; - int32_t drift; - int32_t tb_fraction_of_lp_delta; - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TCOOR_SYNCHRONIZED); - - if (nrf_802154_hp_timer_sync_time_get(&sync_time.hp_timer_time)) - { - sync_time.lp_timer_time = nrf_802154_lp_timer_sync_time_get(); - - // Calculate timers drift - if (m_synchronized) - { - lp_delta = sync_time.lp_timer_time - m_last_sync.lp_timer_time; - hp_delta = sync_time.hp_timer_time - m_last_sync.hp_timer_time; - tb_fraction_of_lp_delta = DIV_ROUND_POSITIVE(lp_delta, TIME_BASE); - timers_diff = hp_delta - lp_delta; - drift = DIV_ROUND(timers_diff, tb_fraction_of_lp_delta); // Drift in PPTB - - if (m_drift_known) - { - m_drift = DIV_ROUND((m_drift * (EWMA_COEF - 1) + drift), EWMA_COEF); - } - else - { - m_drift = drift; - } - - m_drift_known = true; - } - - /* To avoid possible race when nrf_802154_timer_coord_timestamp_get - * is called when m_last_sync is being assigned report that we are not synchronized - * during assignment. - * This is naive solution that can be improved if needed with double buffering. - */ - m_synchronized = false; - __DMB(); - m_last_sync = sync_time; - __DMB(); - m_synchronized = true; - - nrf_802154_hp_timer_sync_prepare(); - nrf_802154_lp_timer_sync_start_at(m_last_sync.lp_timer_time, - m_drift_known ? RESYNC_TIME : FIRST_RESYNC_TIME); - } - else - { - nrf_802154_hp_timer_sync_prepare(); - nrf_802154_lp_timer_sync_start_now(); - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TCOOR_SYNCHRONIZED); -} - -#else // NRF_802154_FRAME_TIMESTAMP_ENABLED - -void nrf_802154_timer_coord_init(void) -{ - // Intentionally empty -} - -void nrf_802154_timer_coord_uninit(void) -{ - // Intentionally empty -} - -void nrf_802154_timer_coord_start(void) -{ - // Intentionally empty -} - -void nrf_802154_timer_coord_stop(void) -{ - // Intentionally empty -} - -void nrf_802154_timer_coord_timestamp_prepare(uint32_t event_addr) -{ - (void)event_addr; - - // Intentionally empty -} - -bool nrf_802154_timer_coord_timestamp_get(uint32_t * p_timestamp) -{ - (void)p_timestamp; - - // Intentionally empty - - return false; -} - -#endif // NRF_802154_FRAME_TIMESTAMP_ENABLED diff --git a/src/nrf_802154_trx.c b/src/nrf_802154_trx.c new file mode 100644 index 0000000..d5d13ec --- /dev/null +++ b/src/nrf_802154_trx.c @@ -0,0 +1,2466 @@ +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_TRX + +#include "nrf_802154_trx.h" + +#include +#include + +#include "nrf_802154_config.h" +#include "nrf_802154_const.h" +#include "nrf_802154_nrfx_addons.h" +#include "nrf_802154_types.h" +#include "nrf_802154_peripherals.h" +#include "nrf_802154_pib.h" +#include "nrf_802154_rssi.h" +#include "nrf_802154_swi.h" +#include "nrf_802154_trx_ppi_api.h" +#include "nrf_802154_utils.h" + +#include "hal/nrf_egu.h" +#include "hal/nrf_radio.h" +#include "hal/nrf_timer.h" + +#include "nrf_802154_procedures_duration.h" +#include "nrf_802154_critical_section.h" +#include "fem/nrf_fem_protocol_api.h" +#include "platform/irq/nrf_802154_irq.h" + +#include "nrf_802154_sl_ant_div.h" + +#define EGU_SYNC_EVENT NRF_EGU_EVENT_TRIGGERED3 +#define EGU_SYNC_TASK NRF_EGU_TASK_TRIGGER3 +#define EGU_SYNC_INTMASK NRF_EGU_INT_TRIGGERED3 + +#if defined(NRF52840_XXAA) || \ + defined(NRF52833_XXAA) || \ + defined(NRF52820_XXAA) || \ + defined(NRF52811_XXAA) +#define PPI_CCAIDLE_FEM NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE ///< PPI that connects RADIO CCAIDLE event with GPIOTE tasks used by FEM +#define RADIO_BASE NRF_RADIO_BASE +#elif defined(NRF5340_XXAA) +#define PPI_CCAIDLE_FEM 0 +#define RADIO_BASE NRF_RADIO_NS_BASE +#endif + +#if NRF_802154_DISABLE_BCC_MATCHING +#define SHORT_ADDRESS_BCSTART 0UL +#else // NRF_802154_DISABLE_BCC_MATCHING +#define SHORT_ADDRESS_BCSTART NRF_RADIO_SHORT_ADDRESS_BCSTART_MASK +#endif // NRF_802154_DISABLE_BCC_MATCHING + +/// Value set to SHORTS register when no shorts should be enabled. +#define SHORTS_IDLE 0 + +/// Value set to SHORTS register for RX operation. +#define SHORTS_RX (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ + NRF_RADIO_SHORT_END_DISABLE_MASK | \ + SHORT_ADDRESS_BCSTART) + +#define SHORTS_RX_FREE_BUFFER (NRF_RADIO_SHORT_RXREADY_START_MASK) + +#define SHORTS_TX_ACK (NRF_RADIO_SHORT_TXREADY_START_MASK | \ + NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) + +#define SHORTS_CCA_TX (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ + NRF_RADIO_SHORT_CCABUSY_DISABLE_MASK | \ + NRF_RADIO_SHORT_CCAIDLE_TXEN_MASK | \ + NRF_RADIO_SHORT_TXREADY_START_MASK | \ + NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) + +#define SHORTS_TX (NRF_RADIO_SHORT_TXREADY_START_MASK | \ + NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) + +#define SHORTS_RX_ACK (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ + NRF_RADIO_SHORT_END_DISABLE_MASK) + +#define SHORTS_MOD_CARRIER (NRF_RADIO_SHORT_TXREADY_START_MASK | \ + NRF_RADIO_SHORT_PHYEND_START_MASK) + +#define SHORTS_ED (NRF_RADIO_SHORT_READY_EDSTART_MASK) + +#define SHORTS_CCA (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ + NRF_RADIO_SHORT_CCABUSY_DISABLE_MASK) + +#define CRC_LENGTH 2 ///< Length of CRC in 802.15.4 frames [bytes] +#define CRC_POLYNOMIAL 0x011021 ///< Polynomial used for CRC calculation in 802.15.4 frames + +#define TXRU_TIME 40 ///< Transmitter ramp up time [us] +#define EVENT_LAT 23 ///< END event latency [us] +#define MAX_RXRAMPDOWN_CYCLES 32 ///< Maximum number of cycles that RX ramp-down might take + +#define RSSI_SETTLE_TIME_US 15 ///< Time required for RSSI measurements to become valid after signal level change. + +#if NRF_802154_INTERNAL_RADIO_IRQ_HANDLING +void nrf_802154_radio_irq_handler(void); ///< Prototype required by internal RADIO IRQ handler +#endif // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING + +/// Common parameters for the FAL handling. +static const nrf_802154_fal_event_t m_activate_rx_cc0 = +{ + .type = NRF_802154_FAL_EVENT_TYPE_TIMER, + .override_ppi = false, + .event.timer = + { + .p_timer_instance = NRF_802154_TIMER_INSTANCE, + .compare_channel_mask = ((1 << NRF_TIMER_CC_CHANNEL0) | (1 << NRF_TIMER_CC_CHANNEL2)), + .counter_period = { + .end = RX_RAMP_UP_TIME + }, + }, +}; + +static const nrf_802154_fal_event_t m_activate_tx_cc0 = +{ + .type = NRF_802154_FAL_EVENT_TYPE_TIMER, + .override_ppi = false, + .event.timer = + { + .p_timer_instance = NRF_802154_TIMER_INSTANCE, + .compare_channel_mask = ((1 << NRF_TIMER_CC_CHANNEL0) | (1 << NRF_TIMER_CC_CHANNEL2)), + .counter_period = { + .end = TX_RAMP_UP_TIME + }, + }, +}; + +static const nrf_802154_fal_event_t m_ccaidle = +{ + .type = NRF_802154_FAL_EVENT_TYPE_GENERIC, + .override_ppi = true, + .ppi_ch_id = PPI_CCAIDLE_FEM, + .event.generic.register_address = ((uint32_t)RADIO_BASE + (uint32_t)NRF_RADIO_EVENT_CCAIDLE) +}; + +/**@brief Fal event used by @ref nrf_802154_trx_transmit_ack and @ref txack_finish */ +static nrf_802154_fal_event_t m_activate_tx_cc0_timeshifted; + +static volatile trx_state_t m_trx_state; + +typedef struct +{ +#if !NRF_802154_DISABLE_BCC_MATCHING + bool psdu_being_received; ///< If PSDU is currently being received. + +#endif + + bool missing_receive_buffer; ///!< If trx entered receive state without receive buffer + +#if NRF_802154_TX_STARTED_NOTIFY_ENABLED + bool tx_started; ///< If the requested transmission has started. + +#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED + + bool rssi_started; + + volatile bool rssi_settled; +} nrf_802154_flags_t; + +static nrf_802154_flags_t m_flags; ///< Flags used to store the current driver state. + +/**@brief Value of TIMER internal counter from which the counting is resumed on RADIO.EVENTS_END event. */ +static volatile uint32_t m_timer_value_on_radio_end_event; +static volatile bool m_transmit_with_cca; + +static void rxframe_finish_disable_ppis(void); +static void rxack_finish_disable_ppis(void); +static void txframe_finish_disable_ppis(bool cca); + +static void go_idle_abort(void); +static void receive_frame_abort(void); +static void receive_ack_abort(void); +static void transmit_frame_abort(void); +static void transmit_ack_abort(void); +static void standalone_cca_abort(void); +static void continuous_carrier_abort(void); +static void modulated_carrier_abort(void); +static void energy_detection_abort(void); + +/** Clear flags describing frame being received. */ +void rx_flags_clear(void) +{ + m_flags.missing_receive_buffer = false; +#if !NRF_802154_DISABLE_BCC_MATCHING + m_flags.psdu_being_received = false; +#endif // !NRF_802154_DISABLE_BCC_MATCHING +} + +static void * volatile mp_receive_buffer; + +/** Initialize TIMER peripheral used by the driver. */ +void nrf_timer_init(void) +{ + nrf_timer_mode_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_MODE_TIMER); + nrf_timer_bit_width_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_BIT_WIDTH_32); + nrf_timer_frequency_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_FREQ_1MHz); + +#if NRF_802154_DISABLE_BCC_MATCHING + // Setup timer for detecting PSDU reception. + nrf_timer_mode_set(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_MODE_COUNTER); + nrf_timer_bit_width_set(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_BIT_WIDTH_8); +#endif +} + +/** Reset radio peripheral. */ +static void nrf_radio_reset(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + nrf_radio_power_set(NRF_RADIO, false); + nrf_radio_power_set(NRF_RADIO, true); + + nrf_802154_log_global_event(NRF_802154_LOG_VERBOSITY_LOW, + NRF_802154_LOG_GLOBAL_EVENT_ID_RADIO_RESET, 0U); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void channel_set(uint8_t channel) +{ + assert(channel >= 11U && channel <= 26U); + + nrf_radio_frequency_set(NRF_RADIO, 2405U + 5U * (channel - 11U)); +} + +static void cca_configuration_update(void) +{ + nrf_802154_cca_cfg_t cca_cfg; + + nrf_802154_pib_cca_cfg_get(&cca_cfg); + nrf_radio_cca_configure(NRF_RADIO, + cca_cfg.mode, + nrf_802154_rssi_cca_ed_threshold_corrected_get(cca_cfg.ed_threshold), + cca_cfg.corr_threshold, + cca_cfg.corr_limit); +} + +/** Initialize interrupts for radio peripheral. */ +static void irq_init(void) +{ +#if !NRF_802154_IRQ_PRIORITY_ALLOWED(NRF_802154_IRQ_PRIORITY) +#error NRF_802154_IRQ_PRIORITY value out of the allowed range. +#endif + +#if NRF_802154_INTERNAL_RADIO_IRQ_HANDLING + nrf_802154_irq_init(RADIO_IRQn, NRF_802154_IRQ_PRIORITY, nrf_802154_radio_irq_handler); + nrf_802154_irq_enable(RADIO_IRQn); +#endif +} + +static void trigger_disable_to_start_rampup(void) +{ + if (!nrf_802154_trx_ppi_for_ramp_up_was_triggered()) + { + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + } +} + +/** Configure FEM to set LNA at appropriate time. */ +static void fem_for_lna_set(void) +{ + if (nrf_802154_fal_lna_configuration_set(&m_activate_rx_cc0, NULL) == NRFX_SUCCESS) + { + nrf_timer_shorts_enable(m_activate_rx_cc0.event.timer.p_timer_instance, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + + nrf_802154_trx_ppi_for_fem_set(); + } +} + +/** Reset FEM configuration for LNA. */ +static void fem_for_lna_reset(void) +{ + nrf_802154_fal_lna_configuration_clear(); + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + nrf_802154_trx_ppi_for_fem_clear(); +} + +/** Configure FEM to set PA at appropriate time. + * + * @note This function must be called before ramp up PPIs are configured. + */ +static void fem_for_pa_set(void) +{ + if (nrf_802154_fal_pa_configuration_set(&m_activate_tx_cc0, NULL) == NRFX_SUCCESS) + { + nrf_timer_shorts_enable(m_activate_tx_cc0.event.timer.p_timer_instance, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + nrf_802154_trx_ppi_for_fem_set(); + } +} + +/** Reset FEM configuration for PA. + * + * @note This function must be called before ramp up PPIs are configured. + */ +static void fem_for_pa_reset(void) +{ + nrf_802154_fal_pa_configuration_clear(); + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + nrf_802154_trx_ppi_for_fem_clear(); + nrf_802154_fal_deactivate_now(NRF_802154_FAL_PA); +} + +/** Configure FEM for TX procedure. + * + * @note This function must be called before ramp up PPIs are configured. + */ +static void fem_for_tx_set(bool cca) +{ + bool success; + + if (cca) + { + bool pa_set = false; + bool lna_set = false; + + if (nrf_802154_fal_lna_configuration_set(&m_activate_rx_cc0, &m_ccaidle) == NRFX_SUCCESS) + { + lna_set = true; + } + + if (nrf_802154_fal_pa_configuration_set(&m_ccaidle, NULL) == NRFX_SUCCESS) + { + pa_set = true; + } + + success = pa_set || lna_set; + + } + else + { + success = (nrf_802154_fal_pa_configuration_set(&m_activate_tx_cc0, NULL) == NRFX_SUCCESS); + } + + if (success) + { + nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + nrf_802154_trx_ppi_for_fem_set(); + } +} + +static void fem_for_tx_reset(bool cca) +{ + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + + if (cca) + { + nrf_802154_fal_lna_configuration_clear(); + nrf_802154_fal_pa_configuration_clear(); + } + else + { + nrf_802154_fal_pa_configuration_clear(); + } + + nrf_802154_trx_ppi_for_fem_clear(); + nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait(); + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); +} + +void nrf_802154_trx_module_reset(void) +{ + m_trx_state = TRX_STATE_DISABLED; + m_timer_value_on_radio_end_event = 0; + m_transmit_with_cca = false; + mp_receive_buffer = NULL; + + memset(&m_flags, 0, sizeof(m_flags)); +} + +void nrf_802154_trx_init(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + nrf_802154_trx_module_reset(); + + nrf_timer_init(); +#if defined(RADIO_INTENSET_SYNC_Msk) + nrf_802154_swi_init(); +#endif + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +void nrf_802154_trx_enable(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert(m_trx_state == TRX_STATE_DISABLED); + + nrf_radio_reset(); + + nrf_radio_packet_conf_t packet_conf; + + nrf_radio_mode_set(NRF_RADIO, NRF_RADIO_MODE_IEEE802154_250KBIT); + + memset(&packet_conf, 0, sizeof(packet_conf)); + packet_conf.lflen = 8; + packet_conf.plen = NRF_RADIO_PREAMBLE_LENGTH_32BIT_ZERO; + packet_conf.crcinc = true; + packet_conf.maxlen = MAX_PACKET_SIZE; + nrf_radio_packet_configure(NRF_RADIO, &packet_conf); + + nrf_radio_modecnf0_set(NRF_RADIO, true, 0); + + // Configure CRC + nrf_radio_crc_configure(NRF_RADIO, CRC_LENGTH, NRF_RADIO_CRC_ADDR_IEEE802154, CRC_POLYNOMIAL); + + // Configure CCA + cca_configuration_update(); + + // Set channel + channel_set(nrf_802154_pib_channel_get()); + + irq_init(); + + assert(nrf_radio_shorts_get(NRF_RADIO) == SHORTS_IDLE); + +#if defined(NRF52840_XXAA) || \ + defined(NRF52833_XXAA) || \ + defined(NRF52820_XXAA) || \ + defined(NRF52811_XXAA) + // TODO: Uncomment it when FEM API is cross-family + nrf_802154_fal_abort_set(nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_DISABLED), + nrf_802154_trx_ppi_group_for_abort_get()); +#endif + + nrf_802154_fal_deactivate_now(NRF_802154_FAL_ALL); + + m_trx_state = TRX_STATE_IDLE; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void ppi_all_clear(void) +{ + switch (m_trx_state) + { + case TRX_STATE_IDLE: + case TRX_STATE_GOING_IDLE: + case TRX_STATE_RXFRAME_FINISHED: + case TRX_STATE_FINISHED: + // Intentionally empty. PPIs are not configured in this state. + break; + + case TRX_STATE_RXFRAME: + rxframe_finish_disable_ppis(); + break; + + case TRX_STATE_RXACK: + rxack_finish_disable_ppis(); + nrf_802154_trx_ppi_for_fem_clear(); + break; + + case TRX_STATE_TXFRAME: + txframe_finish_disable_ppis(m_transmit_with_cca); + nrf_802154_trx_ppi_for_fem_clear(); + break; + + case TRX_STATE_TXACK: + nrf_802154_trx_ppi_for_ack_tx_clear(); + // FEM PPIs are not configured for this state. TIMER was started in TRX_STATE_RXFRAME + // and PPIs starting timer were cleared when exiting TRX_STATE_RXFRAME. + break; + + case TRX_STATE_STANDALONE_CCA: + nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_RXEN, false); + nrf_802154_trx_ppi_for_fem_clear(); + break; + + case TRX_STATE_CONTINUOUS_CARRIER: + nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_TXEN, false); + nrf_802154_trx_ppi_for_fem_clear(); + break; + + case TRX_STATE_MODULATED_CARRIER: + nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_TXEN, false); + nrf_802154_trx_ppi_for_fem_clear(); + break; + + case TRX_STATE_ENERGY_DETECTION: + nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_RXEN, false); + nrf_802154_trx_ppi_for_fem_clear(); + break; + + default: + assert(false); + } +} + +static void fem_power_down_now(void) +{ + nrf_802154_fal_deactivate_now(NRF_802154_FAL_ALL); + + if (nrf_802154_trx_ppi_for_fem_powerdown_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL0)) + { + // FEM requires timer to run to perform powering down operation + nrf_timer_event_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE0); + + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START); + + while (!nrf_timer_event_check(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE0)) + { + // Wait until the event is set. + // The waiting takes several microseconds + } + + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + nrf_802154_trx_ppi_for_fem_powerdown_clear(); + } +} + +void nrf_802154_trx_disable(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + if (m_trx_state != TRX_STATE_DISABLED) + { + nrf_radio_power_set(NRF_RADIO, false); + nrf_802154_irq_clear_pending(RADIO_IRQn); + + /* While the RADIO is powered off deconfigure any PPIs used directly by trx module */ + ppi_all_clear(); + +#if !NRF_802154_DISABLE_BCC_MATCHING && defined(RADIO_INTENSET_SYNC_Msk) + nrf_egu_int_disable(NRF_802154_EGU_INSTANCE, EGU_SYNC_INTMASK); + nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_SYNC_EVENT); +#endif + + /* Stop & deconfigure timer */ + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK | + NRF_TIMER_SHORT_COMPARE1_STOP_MASK); + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + + nrf_radio_power_set(NRF_RADIO, true); + +#if defined(NRF52840_XXAA) || \ + defined(NRF52833_XXAA) || \ + defined(NRF52820_XXAA) || \ + defined(NRF52811_XXAA) + // TODO: Uncomment this code when FEM API supports nRF53 + nrf_802154_fal_abort_clear(); +#endif + + // TODO: Deconfigure FAL PA and LNA here? + nrf_802154_fal_deactivate_now(NRF_802154_FAL_ALL); + + if (m_trx_state != TRX_STATE_IDLE) + { + fem_power_down_now(); + } + +#if NRF_802154_DISABLE_BCC_MATCHING + // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. + nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + nrf_timer_shorts_disable(NRF_802154_COUNTER_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE1_STOP_MASK); +#else + m_flags.psdu_being_received = false; +#endif + m_flags.missing_receive_buffer = false; + m_flags.rssi_started = false; +#if NRF_802154_TX_STARTED_NOTIFY_ENABLED + m_flags.tx_started = false; +#endif + + m_trx_state = TRX_STATE_DISABLED; + + nrf_802154_log_global_event(NRF_802154_LOG_VERBOSITY_LOW, + NRF_802154_LOG_GLOBAL_EVENT_ID_RADIO_RESET, 0U); + } + else + { + // Intentionally empty + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void rx_automatic_antenna_handle(void) +{ + switch (m_trx_state) + { + case TRX_STATE_RXFRAME: + case TRX_STATE_RXFRAME_FINISHED: + nrf_802154_sl_ant_div_rx_started_notify(); + break; + + case TRX_STATE_ENERGY_DETECTION: + // Intentionally empty - notification is called from core when requesting energy detection. + // This is done due to possibility of nrf_802154_trx_energy_detection being called multiple times + // during one energy detection from the point of view of application, if the entire procedure does not + // fit in single timeslot. + break; + + case TRX_STATE_TXACK: + nrf_802154_sl_ant_div_txack_notify(); + break; + + default: + assert(false); + break; + } +} + +/** + * Updates the antenna for reception, according to antenna diversity configuration. + */ +static void rx_antenna_update(void) +{ + bool result = true; + nrf_802154_sl_ant_div_mode_t mode = nrf_802154_sl_ant_div_cfg_mode_get( + NRF_802154_SL_ANT_DIV_OP_RX); + + switch (mode) + { + case NRF_802154_SL_ANT_DIV_MODE_DISABLED: + break; + + case NRF_802154_SL_ANT_DIV_MODE_MANUAL: + result = nrf_802154_sl_ant_div_antenna_set( + nrf_802154_sl_ant_div_cfg_antenna_get(NRF_802154_SL_ANT_DIV_OP_RX)); + break; + + case NRF_802154_SL_ANT_DIV_MODE_AUTO: + rx_automatic_antenna_handle(); + break; + + default: + assert(false); + break; + } + + assert(result); +} + +/** + * Updates the antenna for transmission, according to antenna diversity configuration. + * + * Antenna diversity for tx is not currently supported. If antenna diversity is not + * in disabled state, default antenna will always be used for transmission. + */ +static void tx_antenna_update(void) +{ + bool result = true; + nrf_802154_sl_ant_div_mode_t mode = nrf_802154_sl_ant_div_cfg_mode_get( + NRF_802154_SL_ANT_DIV_OP_TX); + + switch (mode) + { + case NRF_802154_SL_ANT_DIV_MODE_DISABLED: + /* Intentionally empty. */ + break; + + case NRF_802154_SL_ANT_DIV_MODE_MANUAL: + result = nrf_802154_sl_ant_div_antenna_set( + nrf_802154_sl_ant_div_cfg_antenna_get(NRF_802154_SL_ANT_DIV_OP_TX)); + break; + + case NRF_802154_SL_ANT_DIV_MODE_AUTO: + default: + assert(false); + break; + } + + if (!result) + { + assert(false); + } +} + +void nrf_802154_trx_antenna_update(void) +{ + assert(m_trx_state != TRX_STATE_DISABLED); + + switch (m_trx_state) + { + case TRX_STATE_RXFRAME: + case TRX_STATE_RXFRAME_FINISHED: + case TRX_STATE_ENERGY_DETECTION: + case TRX_STATE_TXACK: + rx_antenna_update(); + break; + + case TRX_STATE_STANDALONE_CCA: + case TRX_STATE_RXACK: + case TRX_STATE_TXFRAME: + case TRX_STATE_CONTINUOUS_CARRIER: + case TRX_STATE_MODULATED_CARRIER: + tx_antenna_update(); + break; + + default: + /* Intentionally empty */ + break; + } +} + +void nrf_802154_trx_channel_set(uint8_t channel) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + channel_set(channel); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +void nrf_802154_trx_cca_configuration_update(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + cca_configuration_update(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +/** Check if PSDU is currently being received. + * + * @returns True if radio is receiving PSDU, false otherwise. + */ +bool nrf_802154_trx_psdu_is_being_received(void) +{ +#if NRF_802154_DISABLE_BCC_MATCHING + nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, + nrf_timer_capture_task_get(NRF_TIMER_CC_CHANNEL0)); + uint32_t counter = nrf_timer_cc_get(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL0); + + assert(counter <= 1); + + return counter > 0; +#else // NRF_802154_DISABLE_BCC_MATCHING + return m_flags.psdu_being_received; +#endif // NRF_802154_DISABLE_BCC_MATCHING +} + +bool nrf_802154_trx_receive_is_buffer_missing(void) +{ + switch (m_trx_state) + { + case TRX_STATE_RXFRAME: + /* no break */ + case TRX_STATE_RXACK: + return m_flags.missing_receive_buffer; + + default: + assert(!m_flags.missing_receive_buffer); + return false; + } +} + +static void receive_buffer_missing_buffer_set(void * p_receive_buffer) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + uint32_t shorts = SHORTS_IDLE; + + switch (m_trx_state) + { + case TRX_STATE_RXFRAME: + shorts = SHORTS_RX | SHORTS_RX_FREE_BUFFER; + break; + + case TRX_STATE_RXACK: + shorts = SHORTS_RX_ACK | SHORTS_RX_FREE_BUFFER; + break; + + default: + assert(false); + } + + m_flags.missing_receive_buffer = false; + + nrf_radio_packetptr_set(NRF_RADIO, p_receive_buffer); + + nrf_radio_shorts_set(NRF_RADIO, shorts); + + if (nrf_radio_state_get(NRF_RADIO) == NRF_RADIO_STATE_RXIDLE) + { + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_START); + } + + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); +} + +bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + bool result = false; + + mp_receive_buffer = p_receive_buffer; + + if ((p_receive_buffer != NULL) && m_flags.missing_receive_buffer) + { + receive_buffer_missing_buffer_set(p_receive_buffer); + result = true; + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + + return result; +} + +void nrf_802154_trx_receive_frame(uint8_t bcc, + nrf_802154_trx_receive_notifications_t notifications_mask) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + uint32_t ints_to_enable = 0U; + uint32_t shorts = SHORTS_RX; + + // Force the TIMER to be stopped and count from 0. + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + + m_trx_state = TRX_STATE_RXFRAME; + + // Clear filtering flag + rx_flags_clear(); + // Clear the RSSI measurement flag. + m_flags.rssi_started = false; + + m_flags.rssi_settled = false; + + nrf_radio_txpower_set(NRF_RADIO, nrf_802154_pib_tx_power_get()); + + if (mp_receive_buffer != NULL) + { + m_flags.missing_receive_buffer = false; + nrf_radio_packetptr_set(NRF_RADIO, mp_receive_buffer); + shorts |= SHORTS_RX_FREE_BUFFER; + } + else + { + m_flags.missing_receive_buffer = true; + } + + // Set shorts + nrf_radio_shorts_set(NRF_RADIO, shorts); + + // Set BCC +#if !NRF_802154_DISABLE_BCC_MATCHING + assert(bcc != 0U); + nrf_radio_bcc_set(NRF_RADIO, bcc * 8U); +#else + assert(bcc == 0U); + (void)bcc; +#endif // !NRF_802154_DISABLE_BCC_MATCHING + + // Enable IRQs +#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR); + ints_to_enable |= NRF_RADIO_INT_CRCERROR_MASK; +#endif // !NRF_802154_DISABLE_BCC_MATCHING ||NRF_802154_NOTIFY_CRCERROR +#if !NRF_802154_DISABLE_BCC_MATCHING + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH); + ints_to_enable |= NRF_RADIO_INT_BCMATCH_MASK; +#endif // !NRF_802154_DISABLE_BCC_MATCHING + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK); + ints_to_enable |= NRF_RADIO_INT_CRCOK_MASK; + + if ((notifications_mask & TRX_RECEIVE_NOTIFICATION_STARTED) != 0U) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS); + ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; + } + + bool allow_sync_swi = false; + +#ifdef RADIO_INTENSET_SYNC_Msk + if (((notifications_mask & TRX_RECEIVE_NOTIFICATION_PRESTARTED) != 0U) || + (NRF_802154_SL_ANT_DIV_MODE_DISABLED != + nrf_802154_sl_ant_div_cfg_mode_get(NRF_802154_SL_ANT_DIV_OP_RX))) + { + allow_sync_swi = true; + } +#endif + + if (allow_sync_swi) + { +#if (NRF_802154_DISABLE_BCC_MATCHING || !defined(RADIO_INTENSET_SYNC_Msk)) + assert(false); +#else + // The RADIO can't generate interrupt on EVENT_SYNC. Path to generate interrupt: + // RADIO.EVENT_SYNC -> PPI_RADIO_SYNC_EGU_SYNC -> EGU.TASK_SYNC -> EGU.EVENT_SYNC -> + // SWI_IRQHandler (in nrf_802154_swi.c), calls nrf_802154_trx_swi_irq_handler + nrf_802154_trx_ppi_for_radio_sync_set(EGU_SYNC_TASK); + + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_SYNC); + nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_SYNC_EVENT); + nrf_egu_int_enable(NRF_802154_EGU_INSTANCE, EGU_SYNC_INTMASK); +#endif + } + + nrf_radio_int_enable(NRF_RADIO, ints_to_enable); + + // Set FEM + uint32_t delta_time; + + if (nrf_802154_fal_lna_configuration_set(&m_activate_rx_cc0, NULL) == NRFX_SUCCESS) + { + delta_time = nrf_timer_cc_get(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_CC_CHANNEL0); + } + else + { + delta_time = 1; + nrf_timer_cc_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL0, delta_time); + } + + m_timer_value_on_radio_end_event = delta_time; + + // Select antenna + nrf_802154_trx_antenna_update(); + + // Let the TIMER stop on last event required by a FEM + nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + +#if NRF_802154_DISABLE_BCC_MATCHING + nrf_timer_shorts_enable(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE1_STOP_MASK); + nrf_timer_cc_set(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL1, 1); +#endif // NRF_802154_DISABLE_BCC_MATCHING + + // Set PPIs +#if NRF_802154_DISABLE_BCC_MATCHING +#error Configuration unsupported anymore +#endif // NRF_802154_DISABLE_BCC_MATCHING + nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, true); + + trigger_disable_to_start_rampup(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +void nrf_802154_trx_receive_ack(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + uint32_t shorts = SHORTS_RX_ACK; + uint32_t ints_to_enable = 0U; + + m_trx_state = TRX_STATE_RXACK; + + if (mp_receive_buffer != NULL) + { + m_flags.missing_receive_buffer = false; + nrf_radio_packetptr_set(NRF_RADIO, mp_receive_buffer); + shorts |= SHORTS_RX_FREE_BUFFER; + } + else + { + m_flags.missing_receive_buffer = true; + } + + nrf_radio_shorts_set(NRF_RADIO, shorts); + + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS); + ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK); + ints_to_enable |= NRF_RADIO_INT_CRCOK_MASK; + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR); + ints_to_enable |= NRF_RADIO_INT_CRCERROR_MASK; + + nrf_radio_int_enable(NRF_RADIO, ints_to_enable); + + fem_for_lna_set(); + nrf_802154_trx_antenna_update(); + nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, false); + + trigger_disable_to_start_rampup(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +bool nrf_802154_trx_rssi_measure(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + bool result = false; + + if (m_trx_state == TRX_STATE_RXFRAME) + { + // When TRX is in RXFRAME the RADIO may be also ramping down after previous operation or still ramping up + nrf_radio_state_t radio_state = nrf_radio_state_get(NRF_RADIO); + + if ((radio_state == RADIO_STATE_STATE_RxIdle) || (radio_state == RADIO_STATE_STATE_Rx)) + { + if (!m_flags.rssi_settled) + { + // This operation is requested first time after nrf_802154_trx_receive_frame has been called + // Radio is ramped up, but we need to wait RSSISETTLE time. + // Precisely, we need to wait NRF_RADIO_EVENT_RSSIEND between READY->START short worked + // and RSSI_START task is triggered. Due to limited resources we assume worst case and + // wait whole time when rssi_measure is requested first time after nrf_802154_trx_receive_frame. + nrf_802154_delay_us(RSSI_SETTLE_TIME_US); + m_flags.rssi_settled = true; + } + + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND); + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RSSISTART); + m_flags.rssi_started = true; + + result = true; + } + else + { + // The RADIO may be: + // - still ramping down after transmit + // - ramping up for receive + // - ramping down after frame is received (shorts) + } + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + + return result; +} + +bool nrf_802154_trx_rssi_measure_is_started(void) +{ + return m_flags.rssi_started; +} + +uint8_t nrf_802154_trx_rssi_last_sample_get(void) +{ + return nrf_radio_rssi_sample_get(NRF_RADIO); +} + +bool nrf_802154_trx_rssi_sample_is_available(void) +{ + return nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND); +} + +void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer, + bool cca, + nrf_802154_trx_transmit_notifications_t notifications_mask) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + uint32_t ints_to_enable = 0U; + + // Force the TIMER to be stopped and count from 0. + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + + m_trx_state = TRX_STATE_TXFRAME; + m_transmit_with_cca = cca; + + nrf_radio_txpower_set(NRF_RADIO, nrf_802154_pib_tx_power_get()); + nrf_radio_packetptr_set(NRF_RADIO, p_transmit_buffer); + + // Set shorts + if (cca) + { + nrf_radio_shorts_set(NRF_RADIO, SHORTS_CCA_TX); + } + else + { + nrf_radio_shorts_set(NRF_RADIO, SHORTS_TX); + } + + // Enable IRQs + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND); + ints_to_enable |= NRF_RADIO_INT_PHYEND_MASK; + + if (cca) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY); + + ints_to_enable |= NRF_RADIO_INT_CCABUSY_MASK; + + if ((notifications_mask & TRX_TRANSMIT_NOTIFICATION_CCAIDLE) != 0U) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE); + ints_to_enable |= NRF_RADIO_INT_CCAIDLE_MASK; + } + + if ((notifications_mask & TRX_TRANSMIT_NOTIFICATION_CCASTARTED) != 0U) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY); + ints_to_enable |= NRF_RADIO_INT_READY_MASK; + } + } + + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS); +#if NRF_802154_TX_STARTED_NOTIFY_ENABLED + ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; + m_flags.tx_started = false; +#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED + + nrf_radio_int_enable(NRF_RADIO, ints_to_enable); + + fem_for_tx_set(cca); + nrf_802154_trx_antenna_update(); + nrf_802154_trx_ppi_for_ramp_up_set(cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, false); + + trigger_disable_to_start_rampup(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_us) +{ + /* Assumptions on peripherals + * TIMER is running, is counting from value saved in m_timer_value_on_radio_end_event, + * which trigered on END event, which happened EVENT_LAT us after frame on air receive was finished. + * RADIO is DISABLED + * PPIs are DISABLED + */ + + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + bool result = false; + + assert(m_trx_state == TRX_STATE_RXFRAME_FINISHED); + assert(p_transmit_buffer != NULL); + + m_trx_state = TRX_STATE_TXACK; + + // Set TIMER's CC to the moment when ramp-up should occur. + if (delay_us <= TXRU_TIME + EVENT_LAT) + { + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; + } + + uint32_t timer_cc_ramp_up_start = m_timer_value_on_radio_end_event + delay_us - TXRU_TIME - + EVENT_LAT; + + nrf_timer_cc_set(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_CC_CHANNEL1, + timer_cc_ramp_up_start); + + nrf_radio_packetptr_set(NRF_RADIO, p_transmit_buffer); + + // Set shorts + nrf_radio_shorts_set(NRF_RADIO, SHORTS_TX_ACK); + + // Clear TXREADY event to detect if PPI worked + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_TXREADY); + + // Set FEM + // Note: the TIMER is running, ramp up will start in timer_cc_ramp_up_start tick + // Assumption here is that FEM activation takes no more than TXRU_TIME. + m_activate_tx_cc0_timeshifted = m_activate_tx_cc0; + + // Set the moment for FEM at which real transmission starts. + m_activate_tx_cc0_timeshifted.event.timer.counter_period.end = timer_cc_ramp_up_start + + TXRU_TIME; + + if (nrf_802154_fal_pa_configuration_set(&m_activate_tx_cc0_timeshifted, NULL) == NRFX_SUCCESS) + { + // FEM scheduled its operations on timer, so the timer must be running until last + // operation scheduled by the FEM (TIMER's CC0), which is later than radio ramp up + nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + } + else + { + // FEM didn't schedule anything on timer, so the timer may be stopped when radio ramp-up + // is triggered + nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE1_STOP_MASK); + } + + // Select antenna + nrf_802154_trx_antenna_update(); + + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND); +#if NRF_802154_TX_STARTED_NOTIFY_ENABLED + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS); +#endif + + // Set PPIs + nrf_802154_trx_ppi_for_ack_tx_set(); + + // Since this point the transmission is armed on TIMER's CC1 + + // Detect if PPI will work in future or has just worked. + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_CAPTURE3); + uint32_t timer_cc_now = nrf_timer_cc_get(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_CC_CHANNEL3); + uint32_t timer_cc_fem_start = nrf_timer_cc_get(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_CC_CHANNEL0); + + // When external PA uses a timer, it should be configured to a time later than ramp up time. In + // such case, the timer stops with shorts on PA timer. But if external PA does not use a timer, + // FEM time is set to a value in the past that was used by LNA. After the timer overflows, + // the timer stops with a short on the past value used by LNA. We have to detect if the current + // timer value is after the overflow. + if ((timer_cc_now < timer_cc_ramp_up_start) && + ((timer_cc_fem_start >= timer_cc_ramp_up_start) || (timer_cc_now > timer_cc_fem_start))) + { + result = true; + } + else + { + nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait(); + + if (nrf_radio_state_get(NRF_RADIO) == NRF_RADIO_STATE_TXRU) + { + result = true; + } + else if (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_TXREADY)) + { + result = true; + } + else + { + result = false; + } + } + + if (result) + { + uint32_t ints_to_enable = NRF_RADIO_INT_PHYEND_MASK; + +#if NRF_802154_TX_STARTED_NOTIFY_ENABLED + ints_to_enable |= NRF_RADIO_INT_ADDRESS_MASK; +#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED + + nrf_radio_int_enable(NRF_RADIO, ints_to_enable); + } + else + { + /* We were to late with setting up PPI_TIMER_ACK, ack transmission was not triggered and + * will not be triggered in future. + */ + nrf_802154_trx_ppi_for_ack_tx_clear(); + + /* As the timer was running during operation, it is possible we were able to configure + * FEM thus it may trigger in future or may started PA activation. + */ + nrf_802154_fal_pa_configuration_clear(); + nrf_802154_fal_deactivate_now(NRF_802154_FAL_PA); + + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + + /* No callbacks will be called */ + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + + return result; +} + +static inline void wait_until_radio_is_disabled(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + bool radio_is_disabled = false; + + // RADIO should enter DISABLED state after no longer than RX ramp-down time, which is equal + // approximately 0.5us. Taking a bold assumption that a single iteration of the loop takes + // one cycle to complete, 32 iterations would amount to exactly 0.5 us of execution time. + // Please note that this approach ignores software latency completely, i.e. RADIO should + // have changed state already before entering this function due to ISR processing delays. + for (uint32_t i = 0; i < MAX_RXRAMPDOWN_CYCLES; i++) + { + if (nrf_radio_state_get(NRF_RADIO) == NRF_RADIO_STATE_DISABLED) + { + radio_is_disabled = true; + break; + } + } + + assert(radio_is_disabled); + (void)radio_is_disabled; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void rxframe_finish_disable_ppis(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_RXEN, true); +#if defined(RADIO_INTENSET_SYNC_Msk) + nrf_802154_trx_ppi_for_radio_sync_clear(EGU_SYNC_TASK); +#endif + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void rxframe_finish_disable_fem_activation(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + // Disable LNA activation + nrf_802154_fal_lna_configuration_clear(); + // Disable short used by LNA activation + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void rxframe_finish_disable_ints(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + uint32_t ints_to_disable = NRF_RADIO_INT_CRCOK_MASK | NRF_RADIO_INT_ADDRESS_MASK; + +#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR + ints_to_disable |= NRF_RADIO_INT_CRCERROR_MASK; +#endif // !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR +#if !NRF_802154_DISABLE_BCC_MATCHING + ints_to_disable |= NRF_RADIO_INT_BCMATCH_MASK; +#endif // !NRF_802154_DISABLE_BCC_MATCHING + nrf_radio_int_disable(NRF_RADIO, ints_to_disable); + +#if !NRF_802154_DISABLE_BCC_MATCHING && defined(RADIO_INTENSET_SYNC_Msk) + nrf_egu_int_disable(NRF_802154_EGU_INSTANCE, EGU_SYNC_INTMASK); +#endif + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void rxframe_finish_psdu_is_not_being_received(void) +{ +#if NRF_802154_DISABLE_BCC_MATCHING + // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. + nrf_timer_task_trigger(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + nrf_timer_shorts_disable(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE1_STOP_MASK); +#else + m_flags.psdu_being_received = false; +#endif // NRF_802154_DISABLE_BCC_MATCHING +} + +static void rxframe_finish(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + /* Note that CRCOK/CRCERROR event is generated several cycles before END event. + * + * Below shown what is happening in the hardware + * + * TIMER is started by path: + * RADIO.SHORT_END_DISABLE -> RADIO.TASKS_DISABLE -> RADIO.EVENTS_DISABLED -> + * PPI_DISABLED_EGU -> EGU.TASKS_TRIGGER -> EGU.EVENTS_TRIGGERED -> PPI_EGU_TIMER_START -> TIMER.TASKS_START + * + * FEM's LNA mode is disabled by path: + * RADIO.SHORT_END_DISABLE -> RADIO.TASKS_DISABLE -> RADIO.EVENTS_DISABLED -> (FEM's PPI triggering disable LNA operation, + * see nrf_802154_fal_abort_set() ) + * + * RADIO will not ramp up, as PPI_EGU_RAMP_UP channel is self-disabling, and + * it was disabled when receive ramp-up was started. + */ + wait_until_radio_is_disabled(); // This includes waiting since CRCOK/CRCERROR (several cycles) event until END + // and then during RXDISABLE state (0.5us) + + nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait(); + + /* Now it is guaranteed, that: + * - FEM operation to disable LNA mode is triggered through FEM's PPIs + * - TIMER is started again allowing operation of nrf_802154_trx_transmit_ack + */ + + rxframe_finish_disable_ppis(); + rxframe_finish_disable_fem_activation(); + rxframe_finish_psdu_is_not_being_received(); + rxframe_finish_disable_ints(); + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); + m_flags.missing_receive_buffer = false; + + /* Current state of peripherals: + * RADIO is DISABLED + * FEM is powered but LNA mode has just been turned off + * TIMER is running, counting from the value stored in m_timer_value_on_radio_end_event + * All PPIs used by receive operation are disabled, forks are cleared, PPI groups that were used are cleared + * RADIO.SHORTS are cleared + */ + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_abort(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + switch (m_trx_state) + { + case TRX_STATE_DISABLED: + case TRX_STATE_IDLE: + case TRX_STATE_FINISHED: + /* Nothing to do, intentionally empty */ + break; + + case TRX_STATE_GOING_IDLE: + go_idle_abort(); + break; + + case TRX_STATE_RXFRAME: + receive_frame_abort(); + break; + + case TRX_STATE_RXFRAME_FINISHED: + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + m_trx_state = TRX_STATE_FINISHED; + break; + + case TRX_STATE_RXACK: + receive_ack_abort(); + break; + + case TRX_STATE_TXFRAME: + transmit_frame_abort(); + break; + + case TRX_STATE_TXACK: + transmit_ack_abort(); + break; + + case TRX_STATE_STANDALONE_CCA: + standalone_cca_abort(); + break; + + case TRX_STATE_CONTINUOUS_CARRIER: + continuous_carrier_abort(); + break; + + case TRX_STATE_MODULATED_CARRIER: + modulated_carrier_abort(); + break; + + case TRX_STATE_ENERGY_DETECTION: + energy_detection_abort(); + break; + + default: + assert(false); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +trx_state_t nrf_802154_trx_state_get(void) +{ + return m_trx_state; +} + +static void go_idle_from_state_finished(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + m_trx_state = TRX_STATE_GOING_IDLE; + + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED); + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + nrf_radio_int_enable(NRF_RADIO, NRF_RADIO_INT_DISABLED_MASK); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +bool nrf_802154_trx_go_idle(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + bool result = false; + + switch (m_trx_state) + { + case TRX_STATE_DISABLED: + assert(false); + break; + + case TRX_STATE_IDLE: + /* There will be no callout */ + break; + + case TRX_STATE_GOING_IDLE: + /* There will be callout */ + result = true; + break; + + case TRX_STATE_RXFRAME_FINISHED: + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + /* Fallthrough */ + + case TRX_STATE_FINISHED: + go_idle_from_state_finished(); + result = true; + break; + + default: + assert(false); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + + return result; +} + +static void go_idle_abort(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_DISABLED_MASK); + m_trx_state = TRX_STATE_FINISHED; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void receive_frame_abort(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + rxframe_finish_disable_ppis(); + rxframe_finish_disable_fem_activation(); + rxframe_finish_psdu_is_not_being_received(); + rxframe_finish_disable_ints(); + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); + + m_flags.missing_receive_buffer = false; + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + + m_trx_state = TRX_STATE_FINISHED; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void rxack_finish_disable_ppis(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_RXEN, false); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void rxack_finish_disable_ints(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_radio_int_disable(NRF_RADIO, + NRF_RADIO_INT_ADDRESS_MASK | NRF_RADIO_INT_CRCERROR_MASK | + NRF_RADIO_INT_CRCOK_MASK); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void rxack_finish_disable_fem_activation(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + // Disable LNA activation + nrf_802154_fal_lna_configuration_clear(); + + // Clear LNA PPIs + nrf_802154_trx_ppi_for_fem_clear(); + + // Disable short used by LNA activation + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void rxack_finish(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + rxack_finish_disable_ppis(); + rxack_finish_disable_ints(); + rxack_finish_disable_fem_activation(); + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); + m_flags.missing_receive_buffer = false; + + /* Current state of peripherals + * RADIO is DISABLED + * FEM is powered but LNA mode has just been turned off + * TIMER is shutdown + * PPIs used by receive operation are disabled, forks are cleared, PPI groups used are cleared + * RADIO.SHORTS are cleared + */ + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void receive_ack_abort(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + rxack_finish_disable_ppis(); + rxack_finish_disable_ints(); + rxack_finish_disable_fem_activation(); + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); + m_flags.missing_receive_buffer = false; + + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + + m_trx_state = TRX_STATE_FINISHED; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_standalone_cca(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert((m_trx_state == TRX_STATE_IDLE) || (m_trx_state == TRX_STATE_FINISHED)); + + m_trx_state = TRX_STATE_STANDALONE_CCA; + + // Set shorts + nrf_radio_shorts_set(NRF_RADIO, SHORTS_CCA); + + // Enable IRQs + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY); + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE); + nrf_radio_int_enable(NRF_RADIO, NRF_RADIO_INT_CCABUSY_MASK | NRF_RADIO_INT_CCAIDLE_MASK); + + // Set FEM + fem_for_lna_set(); + + // Select antenna + nrf_802154_trx_antenna_update(); + + // Set PPIs + nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, false); + + trigger_disable_to_start_rampup(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void standalone_cca_finish(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_RXEN, false); + + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); + + fem_for_lna_reset(); + + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_CCABUSY_MASK | NRF_RADIO_INT_CCAIDLE_MASK); + + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_CCASTOP); + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void standalone_cca_abort(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + standalone_cca_finish(); + + m_trx_state = TRX_STATE_FINISHED; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_continuous_carrier(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert((m_trx_state == TRX_STATE_IDLE) || (m_trx_state == TRX_STATE_FINISHED)); + + m_trx_state = TRX_STATE_CONTINUOUS_CARRIER; + + // Set Tx Power + nrf_radio_txpower_set(NRF_RADIO, nrf_802154_pib_tx_power_get()); + + // Set FEM + fem_for_pa_set(); + + // Select antenna + nrf_802154_trx_antenna_update(); + + // Set PPIs + nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_TXEN, false); + + trigger_disable_to_start_rampup(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +void nrf_802154_trx_continuous_carrier_restart(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert(m_trx_state == TRX_STATE_CONTINUOUS_CARRIER); + + // Continuous carrier PPIs are configured without self-disabling + // Triggering RADIO.TASK_DISABLE causes ramp-down -> RADIO.EVENTS_DISABLED -> EGU.TASK -> EGU.EVENT -> + // RADIO.TASK_TXEN -> ramp_up -> new continous carrier + + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void continuous_carrier_abort(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_TXEN, false); + + fem_for_pa_reset(); + + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + m_trx_state = TRX_STATE_FINISHED; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert((m_trx_state == TRX_STATE_IDLE) || (m_trx_state == TRX_STATE_FINISHED)); + assert(p_transmit_buffer != NULL); + + m_trx_state = TRX_STATE_MODULATED_CARRIER; + + // Set Tx Power + nrf_radio_txpower_set(NRF_RADIO, nrf_802154_pib_tx_power_get()); + + // Set Tx buffer + nrf_radio_packetptr_set(NRF_RADIO, p_transmit_buffer); + + // Set shorts + nrf_radio_shorts_set(NRF_RADIO, SHORTS_MOD_CARRIER); + + // Set FEM + fem_for_pa_set(); + + // Select antenna + nrf_802154_trx_antenna_update(); + + // Set PPIs + nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_TXEN, false); + + trigger_disable_to_start_rampup(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +void nrf_802154_trx_modulated_carrier_restart(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert(m_trx_state == TRX_STATE_MODULATED_CARRIER); + + // Modulated carrier PPIs are configured without self-disabling + // Triggering RADIO.TASK_DISABLE causes ramp-down -> RADIO.EVENTS_DISABLED -> EGU.TASK -> EGU.EVENT -> + // RADIO.TASK_TXEN -> ramp_up -> new modulated carrier + + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void modulated_carrier_abort() +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_TXEN, false); + + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); + + fem_for_pa_reset(); + + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + m_trx_state = TRX_STATE_FINISHED; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_energy_detection(uint32_t ed_count) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert((m_trx_state == TRX_STATE_FINISHED) || (m_trx_state == TRX_STATE_IDLE)); + + m_trx_state = TRX_STATE_ENERGY_DETECTION; + + ed_count--; + /* Check that vd_count will fit into defined bits of register */ + assert( (ed_count & (~RADIO_EDCNT_EDCNT_Msk)) == 0U); + + nrf_radio_ed_loop_count_set(NRF_RADIO, ed_count); + + // Set shorts + nrf_radio_shorts_set(NRF_RADIO, SHORTS_ED); + + // Enable IRQs + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_EDEND); + nrf_radio_int_enable(NRF_RADIO, NRF_RADIO_INT_EDEND_MASK); + + // Set FEM + fem_for_lna_set(); + + // Select antenna + nrf_802154_trx_antenna_update(); + + // Set PPIs + nrf_802154_trx_ppi_for_ramp_up_set(NRF_RADIO_TASK_RXEN, false); + + trigger_disable_to_start_rampup(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void energy_detection_finish(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ramp_up_clear(NRF_RADIO_TASK_RXEN, false); + fem_for_lna_reset(); + + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_EDEND_MASK); + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); + + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_EDSTOP); + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void energy_detection_abort(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + energy_detection_finish(); + m_trx_state = TRX_STATE_FINISHED; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void irq_handler_ready(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert(m_trx_state == TRX_STATE_TXFRAME); + + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_READY_MASK); + + nrf_802154_trx_transmit_frame_ccastarted(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void irq_handler_address(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + switch (m_trx_state) + { + case TRX_STATE_RXFRAME: + nrf_802154_trx_receive_frame_started(); + break; + + case TRX_STATE_RXACK: + m_flags.rssi_started = true; + nrf_802154_trx_receive_ack_started(); + break; + +#if NRF_802154_TX_STARTED_NOTIFY_ENABLED + case TRX_STATE_TXFRAME: + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_ADDRESS_MASK); + m_flags.tx_started = true; + nrf_802154_trx_transmit_frame_started(); + break; +#endif // NRF_802154_TX_STARTED_NOTIFY_ENABLED + +#if NRF_802154_TX_STARTED_NOTIFY_ENABLED + case TRX_STATE_TXACK: + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_ADDRESS_MASK); + nrf_802154_trx_transmit_ack_started(); + break; +#endif + + default: + assert(false); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +#if !NRF_802154_DISABLE_BCC_MATCHING +static void irq_handler_bcmatch(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + uint8_t current_bcc; + uint8_t next_bcc; + + assert(m_trx_state == TRX_STATE_RXFRAME); + + m_flags.psdu_being_received = true; + + // If CRCERROR event is set, it means that events are handled out of order due to software + // latency. Just skip this handler in this case - frame will be dropped. + if (nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR)) + { + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return; + } + + current_bcc = nrf_radio_bcc_get(NRF_RADIO) / 8U; + + next_bcc = nrf_802154_trx_receive_frame_bcmatched(current_bcc); + + if (next_bcc > current_bcc) + { + /* Note: If we don't make it before given octet is received by RADIO bcmatch will not be triggered. + * The fact that filtering may be not completed at the call to nrf_802154_trx_receive_received handler + * should be handled by the handler. + */ + nrf_radio_bcc_set(NRF_RADIO, next_bcc * 8); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +#endif + +#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR +static void irq_handler_crcerror(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + switch (m_trx_state) + { + case TRX_STATE_RXFRAME: +#if NRF_802154_DISABLE_BCC_MATCHING + /* The hardware restarts receive at the moment. + * The TIMER is being shutdown and restarted by the hardware see + * PPI_CRCERROR_CLEAR in nrf_802154_trx_receive_frame + */ +#else + rxframe_finish(); + /* On crc error TIMER is not needed, no ACK may be sent */ + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + m_trx_state = TRX_STATE_FINISHED; +#endif + nrf_802154_trx_receive_frame_crcerror(); + break; + + case TRX_STATE_RXACK: + rxack_finish(); + m_trx_state = TRX_STATE_FINISHED; + nrf_802154_trx_receive_ack_crcerror(); + break; + + default: + assert(false); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +#endif + +static void irq_handler_crcok(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + switch (m_trx_state) + { + case TRX_STATE_RXFRAME: + m_flags.rssi_started = true; + rxframe_finish(); + m_trx_state = TRX_STATE_RXFRAME_FINISHED; + nrf_802154_trx_receive_frame_received(); + break; + + case TRX_STATE_RXACK: + rxack_finish(); + m_trx_state = TRX_STATE_FINISHED; + nrf_802154_trx_receive_ack_received(); + break; + + default: + assert(false); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void txframe_finish_disable_ppis(bool cca) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ramp_up_clear(cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, false); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void txframe_finish_disable_ints(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_PHYEND_MASK | + NRF_RADIO_INT_CCAIDLE_MASK | + NRF_RADIO_INT_CCABUSY_MASK | + NRF_RADIO_INT_ADDRESS_MASK | + NRF_RADIO_INT_READY_MASK); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void txframe_finish(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + /* Below shown what is happening in the hardware + * + * Due to short RADIO.SHORT_PHYEND_DISABLE the RADIO is in TXDISABLE (currently ramping down for 21us) state or + * has already reached DISABLED state (if we entered into ISR with greater latency) + * + * Even if RADIO reaches state DISABLED (event DISABLED was triggered by short), no transmission will be triggered + * as PPI_EGU_RAMP_UP is self-disabling PPI channel. + * + * If FEM is in use the PPI_EGU_TIMER_START might be triggered if radio reached DISABLED state, + * so the TIMER may start counting from the value on which FEM activation finished. The TIMER's CC registers + * are set in the past so even if TIMER started no spurious FEM PA activation will occur. + * We need to disable PPI_EGU_TIMER_START and then shutdown TIMER as it is not used. + */ + txframe_finish_disable_ppis(m_transmit_with_cca); + + fem_for_tx_reset(m_transmit_with_cca); + + txframe_finish_disable_ints(); + + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); +#if NRF_802154_TX_STARTED_NOTIFY_ENABLED + m_flags.tx_started = false; +#endif + m_flags.missing_receive_buffer = false; + + /* Current state of peripherals + * RADIO is either in TXDISABLE or DISABLED + * FEM is powered but PA mode will be turned off on entry into DISABLED state or is already turned off + * TIMER is shutdown + * All PPIs that were used are disabled (forks are cleared if used) + * RADIO.SHORTS are cleared + */ + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void transmit_frame_abort(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + txframe_finish_disable_ppis(m_transmit_with_cca); + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); + + fem_for_tx_reset(m_transmit_with_cca); + + txframe_finish_disable_ints(); +#if NRF_802154_TX_STARTED_NOTIFY_ENABLED + m_flags.tx_started = false; +#endif + m_flags.missing_receive_buffer = false; + + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_CCASTOP); + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + m_trx_state = TRX_STATE_FINISHED; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void txack_finish(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + /* Below shown what is happening in the hardware + * + * Due to short RADIO.SHORT_PHYEND_DISABLE the RADIO is in TXDISABLE (currently ramping down for 21us) state or + * has already reached DISABLED state (if we entered into ISR with greater latency) + * + * Even if RADIO reaches state DISABLED (event DISABLED was triggered by short), no transmission will be triggered + * as only PPI_TIMER_TX_ACK was enabled. + * + * FEM will disable PA mode on RADIO.DISABLED event + * + * The TIMER was counting to trigger RADIO ramp up and FEM (if required). The TIMER is configured + * to trigger STOP task on one of these events (whichever is later). As we finished the TIMER is + * stopped now, and there is no PPIs starting it automatically by the hardware. + */ + nrf_802154_trx_ppi_for_ack_tx_clear(); + + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); + + nrf_802154_fal_pa_configuration_clear(); + + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK | + NRF_TIMER_SHORT_COMPARE1_STOP_MASK); + + // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_PHYEND_MASK | NRF_RADIO_INT_ADDRESS_MASK); + + /* Current state of peripherals + * RADIO is either in TXDISABLE or DISABLED + * FEM is powered but PA mode will be turned off on entry into DISABLED state or is already turned off + * TIMER is shutdown + * All PPIs that were used are disabled (forks are cleared if used) + * RADIO.SHORTS are cleared + */ + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void transmit_ack_abort(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ack_tx_clear(); + + nrf_radio_shorts_set(NRF_RADIO, SHORTS_IDLE); + + nrf_802154_fal_pa_configuration_clear(); + + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK | + NRF_TIMER_SHORT_COMPARE1_STOP_MASK); + + // Anomaly 78: use SHUTDOWN instead of STOP and CLEAR. + nrf_timer_task_trigger(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_SHUTDOWN); + + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_PHYEND_MASK | NRF_RADIO_INT_ADDRESS_MASK); + + nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + + m_trx_state = TRX_STATE_FINISHED; + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void irq_handler_phyend(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + switch (m_trx_state) + { + case TRX_STATE_TXFRAME: + txframe_finish(); + m_trx_state = TRX_STATE_FINISHED; + nrf_802154_trx_transmit_frame_transmitted(); + break; + + case TRX_STATE_TXACK: + txack_finish(); + m_trx_state = TRX_STATE_FINISHED; + nrf_802154_trx_transmit_ack_transmitted(); + break; + + default: + assert(false); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void go_idle_finish(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_radio_int_disable(NRF_RADIO, NRF_RADIO_INT_DISABLED_MASK); + + fem_power_down_now(); + + m_trx_state = TRX_STATE_IDLE; + + nrf_802154_trx_go_idle_finished(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +static void irq_handler_disabled(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + switch (m_trx_state) + { + case TRX_STATE_GOING_IDLE: + go_idle_finish(); + break; + + default: + assert(false); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void irq_handler_ccaidle(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + switch (m_trx_state) + { + case TRX_STATE_STANDALONE_CCA: + standalone_cca_finish(); + m_trx_state = TRX_STATE_FINISHED; + nrf_802154_trx_standalone_cca_finished(true); + break; + + case TRX_STATE_TXFRAME: + nrf_802154_trx_transmit_frame_ccaidle(); + break; + + default: + assert(false); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void irq_handler_ccabusy(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + switch (m_trx_state) + { + case TRX_STATE_TXFRAME: + assert(m_transmit_with_cca); + txframe_finish(); + m_trx_state = TRX_STATE_FINISHED; + nrf_802154_trx_transmit_frame_ccabusy(); + break; + + case TRX_STATE_STANDALONE_CCA: + standalone_cca_finish(); + m_trx_state = TRX_STATE_FINISHED; + nrf_802154_trx_standalone_cca_finished(false); + break; + + default: + assert(false); + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +static void irq_handler_edend(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert(m_trx_state == TRX_STATE_ENERGY_DETECTION); + + uint8_t ed_sample = nrf_radio_ed_sample_get(NRF_RADIO); + + energy_detection_finish(); + m_trx_state = TRX_STATE_FINISHED; + + nrf_802154_trx_energy_detection_finished(ed_sample); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +#if defined(RADIO_INTENSET_SYNC_Msk) +static void irq_handler_sync(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + assert(m_trx_state == TRX_STATE_RXFRAME); + + nrf_802154_trx_receive_frame_prestarted(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +#endif + +void nrf_802154_radio_irq_handler(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + // Prevent interrupting of this handler by requests from higher priority code. + nrf_802154_critical_section_forcefully_enter(); + +#if defined(RADIO_INTENSET_SYNC_Msk) + // Note: For NRF_RADIO_EVENT_SYNC we enable interrupt through EGU. + // That's why we check here EGU's EGU_SYNC_INTMASK. + // The RADIO does not have interrupt from SYNC event. + if (nrf_egu_int_enable_check(NRF_802154_EGU_INSTANCE, EGU_SYNC_INTMASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_SYNC)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_SYNC); + nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_SYNC_EVENT); + + irq_handler_sync(); + } +#endif + + if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_READY_MASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_READY)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY); + + irq_handler_ready(); + } + + if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_ADDRESS_MASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS); + + irq_handler_address(); + } + +#if !NRF_802154_DISABLE_BCC_MATCHING + // Check MAC frame header. + if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_BCMATCH_MASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH); + + irq_handler_bcmatch(); + } + +#endif // !NRF_802154_DISABLE_BCC_MATCHING + +#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR + if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_CRCERROR_MASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCERROR); + + irq_handler_crcerror(); + } +#endif // !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR + + if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_CRCOK_MASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CRCOK)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CRCOK); + + irq_handler_crcok(); + } + + if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_PHYEND_MASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_PHYEND)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND); + + irq_handler_phyend(); + } + + if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_DISABLED_MASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_DISABLED)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED); + + irq_handler_disabled(); + } + + if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_CCAIDLE_MASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE); + + irq_handler_ccaidle(); + } + + if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_CCABUSY_MASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY); + + irq_handler_ccabusy(); + } + + if (nrf_radio_int_enable_check(NRF_RADIO, NRF_RADIO_INT_EDEND_MASK) && + nrf_radio_event_check(NRF_RADIO, NRF_RADIO_EVENT_EDEND)) + { + nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_EDEND); + + irq_handler_edend(); + } + + nrf_802154_critical_section_exit(); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); +} + +#if NRF_802154_INTERNAL_RADIO_IRQ_HANDLING +void RADIO_IRQHandler(void) +{ + nrf_802154_radio_irq_handler(); +} + +#endif // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING + +#if defined(RADIO_INTENSET_SYNC_Msk) +void nrf_802154_trx_swi_irq_handler(void) +{ + // If this handler is preempted by MARGIN, RADIO IRQ might be set to pending + // and executed after MARGIN processing is finished, i.e. after the end of a timeslot. + // To prevent that from happening, the handler is executed with disabled interrupts. + nrf_802154_mcu_critical_state_t mcu_crit_state; + + nrf_802154_mcu_critical_enter(mcu_crit_state); + + if (nrf_egu_int_enable_check(NRF_802154_EGU_INSTANCE, EGU_SYNC_INTMASK) && + nrf_egu_event_check(NRF_802154_EGU_INSTANCE, EGU_SYNC_EVENT)) + { + nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_SYNC_EVENT); + + // We are in SWI_IRQHandler, which priority is usually lower than RADIO_IRQHandler. + // To avoid problems with critical sections, trigger RADIO_IRQ manually. + // - If we are not in critical section, RADIO_IRQ will start shortly (calling + // nrf_802154_radio_irq_handler) preempting current SWI_IRQHandler. From + // nrf_802154_radio_irq_handler we acquire critical section and + // process sync event. + // If we are in critical section, the RADIO_IRQ is disabled on NVIC. + // Following will make it pending, and processing of RADIO_IRQ will start + // when critical section is left. + + nrf_802154_irq_set_pending(RADIO_IRQn); + } + + nrf_802154_mcu_critical_exit(mcu_crit_state); +} + +#endif diff --git a/src/nrf_802154_trx.h b/src/nrf_802154_trx.h new file mode 100644 index 0000000..afac842 --- /dev/null +++ b/src/nrf_802154_trx.h @@ -0,0 +1,768 @@ +/* + * Copyright (c) 2019 - 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Module that contains radio hardware-related functions + * of the nRF IEEE 802.15.4 radio driver. + * + * @details + */ + +#ifndef NRF_802154_TRX_H_ +#define NRF_802154_TRX_H_ + +#include +#include + +#include "nrf_802154_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief States of the FSM of the TRX module. */ +typedef enum +{ + TRX_STATE_DISABLED = 0, + TRX_STATE_IDLE, + TRX_STATE_GOING_IDLE, + TRX_STATE_RXFRAME, + + /* PPIS disabled deconfigured + * RADIO is DISABLED, RXDISABLE + * RADIO shorts are 0 + * TIMER is running + * FEM is going to powered or is powered depending if RADIO reached DISABLED + */ + TRX_STATE_RXFRAME_FINISHED, + + TRX_STATE_RXACK, + TRX_STATE_TXFRAME, + TRX_STATE_TXACK, + TRX_STATE_STANDALONE_CCA, + TRX_STATE_CONTINUOUS_CARRIER, + TRX_STATE_MODULATED_CARRIER, + TRX_STATE_ENERGY_DETECTION, + + /* PPIS disabled deconfigured + * RADIO is DISABLED, TXDISABLE, RXDISABLE + * RADIO shorts are 0 + * TIMER is stopped + * FEM is going to powered or is powered depending if RADIO reached DISABLED + */ + TRX_STATE_FINISHED +} trx_state_t; + +/**@brief Notifications that can be enabled for @ref nrf_802154_trx_receive_frame operation. */ +typedef enum +{ + /**@brief No notifications during frame receive provided. */ + TRX_RECEIVE_NOTIFICATION_NONE = 0U, + + /**@brief Notification @ref nrf_802154_trx_receive_frame_prestarted enabled. */ + TRX_RECEIVE_NOTIFICATION_PRESTARTED = (1U << 0), + + /**@brief Notification @ref nrf_802154_trx_receive_frame_started enabled. */ + TRX_RECEIVE_NOTIFICATION_STARTED = (1U << 1), +} nrf_802154_trx_receive_notifications_t; + +/**@brief Notifications that can be enabled for @ref nrf_802154_trx_transmit_frame operation. */ +typedef enum +{ + /**@brief No notifications during frame transmission provided. */ + TRX_TRANSMIT_NOTIFICATION_NONE = 0U, + + /**@brief Notification @ref nrf_802154_trx_transmit_frame_ccaidle */ + TRX_TRANSMIT_NOTIFICATION_CCAIDLE = (1U << 1), + + /**@brief Notification @ref nrf_802154_trx_transmit_frame_ccastarted */ + TRX_TRANSMIT_NOTIFICATION_CCASTARTED = (1U << 2) +} nrf_802154_trx_transmit_notifications_t; + +/**@brief Initializes trx module. + * + * This function must be called exactly once, before any other API call. This function sets internal state + * of trx module into @c DISABLED. It initializes also those peripherals that are used exclusively + * by trx module and are not shared when trx module is in @c DISABLED state. + */ +void nrf_802154_trx_init(void); + +/**@brief Enables trx module. + * + * Effects of call to this function: + * - The RADIO peripheral is fully reset and configured into 802.15.4 mode. + * - FEM module state is set to powered off. + * - PPIs used by trx module are disabled. + * - TIMER used by trx module is shutdown. + * - Trx module is in @c IDLE state + * + * @warning This function may be called when: + * - Trx module was in @c DISABLED state (after @ref nrf_802154_trx_init or after @ref nrf_802154_trx_disable). + * - HFCLK clock is activated. + * - Access to the RADIO peripheral is granted (applicable when the RADIO is shared with other drivers). + * + * @note When trx was in @c DISABLED state, the RADIO might have been controlled by other drivers. Thus + * full reset of the RADIO peripheral is performed. + */ +void nrf_802154_trx_enable(void); + +/**@brief Disables trx module. + * + * This function has no effects when the trx module is in @c DISABLED state. + * Otherwise following effects apply: + * - The RADIO peripheral is fully reset. + * - FEM module state is set to powered off. + * - all PPSs used by trx module are disabled and cleared. + * - TIMER used by trx module is shutdown. + * - Trx module is in @c DISABLED state + * + * @note On call to this function any activity of trx module is stopped. If any operation was executing, it + * will be stopped and no handler will be called. After call HFCLK may be deactivated and + * the RADIO peripheral may be passed to other driver. + */ +void nrf_802154_trx_disable(void); + +/** + * @brief Updates currently used antenna. + * + * This function sets the antenna to be used based on antenna diversity interface + * configuration and TRX state. See @ref nrf_802154_sl_ant_div_mode_set, + * @ref nrf_802154_sl_ant_div_antenna_set. + */ +void nrf_802154_trx_antenna_update(void); + +/**@brief Sets radio channel to use. + * + * @param[in] channel Channel number to set (11-26). + */ +void nrf_802154_trx_channel_set(uint8_t channel); + +/**@brief Updates CCA configuration in the RADIO peripheral according to PIB. */ +void nrf_802154_trx_cca_configuration_update(void); + +/**@brief Puts the trx module into receive frame mode. + * + * The frame will be received into buffer set by @ref nrf_802154_trx_receive_buffer_set. + * + * When NRF_802154_DISABLE_BCC_MATCHING == 0 + * - during receive @ref nrf_802154_trx_receive_frame_started handler is called when + * SHR field of a frame being received is received (only when @p notifications_mask contained @ref TRX_RECEIVE_NOTIFICATION_STARTED flag) + * - during receive @ref nrf_802154_trx_receive_frame_bcmatched handler is called when + * @p bcc octets are received. + * - when a frame is received with correct crc, @ref nrf_802154_trx_receive_frame_received is called + * - when a frame is received with incorrect crc, @ref nrf_802154_trx_receive_frame_crcerror is called + * + * When NRF_802154_DISABLE_BCC_MATCHING != 0 + * - @ref nrf_802154_trx_receive_frame_prestarted handler is called when the RADIO initially syncs on received frame. + * This handler is called when @p notifications_mask contains @ref TRX_RECEIVE_NOTIFICATION_PRESTARTED. + * - @ref nrf_802154_trx_receive_frame_started handler is called when + * SHR field of a frame being received is received (only when @p notifications_mask contained @ref TRX_RECEIVE_NOTIFICATION_STARTED flag) + * - after the frame is received with correct crc, @ref nrf_802154_trx_receive_frame_received is called + * - after the frame is received with incorrect crc: + * - when NRF_802154_NOTIFY_CRCERROR == 0: + * - the hardware restarts receive automatically + * - no handler is called + * - when NRF_802154_NOTIFY_CRCERROR != 0: + * - the hardware restarts receive automatically + * - @ref nrf_802154_trx_receive_frame_crcerror is called + * + * When in @ref nrf_802154_trx_receive_frame_received, the TIMER is running allowing sending response (e.g. ACK frame) + * in time regime by a call to nrf_802154_trx_transmit_after_frame_received. + * + * @note To receive ACK use @ref nrf_802154_trx_receive_ack + * + * @param[in] bcc Number of received bytes after which @ref nrf_802154_trx_receive_frame_bcmatched will be called. + * This must not be zero if @ref NRF_802154_DISABLE_BCC_MATCHING == 0. + * When @ref NRF_802154_DISABLE_BCC_MATCHING != 0, this value must be zero. + * @param[in] notifications_mask Selects additional notifications generated during a frame reception. + * It is bitwise combination of @ref nrf_802154_trx_receive_notifications_t values. + * When NRF_802154_DISABLE_BCC_MATCHING != 0, flag @ref TRX_RECEIVE_NOTIFICATION_PRESTARTED is forbidden. + */ +void nrf_802154_trx_receive_frame(uint8_t bcc, + nrf_802154_trx_receive_notifications_t notifications_mask); + +/**@brief Puts the trx module into receive ACK mode. + * + * The ack frame will be received into buffer set by @ref nrf_802154_trx_receive_buffer_set. + * + * During receive of an ack: + * - @ref nrf_802154_trx_receive_ack_started is called when a frame has just started being received. + * - when a frame is received with correct crc, @ref nrf_802154_trx_receive_ack_received is called. + * - when a frame is received with incorrect crc, @ref nrf_802154_trx_receive_ack_crcerror is called. + * - no bcmatch events are generated. + */ +void nrf_802154_trx_receive_ack(void); + +/**@brief Starts RSSI measurement. + * + * @note This function succeeds when TRX module is in receive frame state only (started with @ref nrf_802154_trx_receive_frame) + * + * @retval true When RSSI measurement has been started. + * @retval false When TRX state didn't allow start of RSSI measurement. + */ +bool nrf_802154_trx_rssi_measure(void); + +/**@brief Checks if RSSI measurement is currently started. + * + * @retval true When RSSI measurement is currently started. In this case user can + * check if RSSI sample is already available by call to @ref nrf_802154_trx_rssi_sample_is_available. + * @retval false When RSSI measurement is not started. + */ +bool nrf_802154_trx_rssi_measure_is_started(void); + +/**@brief Checks if RSSI sample is available. + * + * @retval true When RSSI sample is available. The sample may be read by a call to @ref nrf_802154_trx_rssi_last_sample_get + * @retval false When RSSI sample is unavailable. + */ +bool nrf_802154_trx_rssi_sample_is_available(void); + +/**@brief Returns last measured RSSI sample. + * + * @return RSSI sample. Returned value must be scaled using API provided by nrf_802154_rssi.h. + */ +uint8_t nrf_802154_trx_rssi_last_sample_get(void); + +/**@brief Check if PSDU is currently being received. + * + * @retval true If trx is in receive mode triggered by @ref nrf_802154_trx_receive_frame and + * a frame receive on air has been started but not finished yet. + * @retval false Otherwise. + * + * @note This function returns false when receive has been triggered by @ref nrf_802154_trx_receive_ack + * regardless of the fact if the frame on air has been started or not. + */ +bool nrf_802154_trx_psdu_is_being_received(void); + +/**@brief Checks if current receive operation was started without providing receive buffer. + * + * It may happen that @ref nrf_802154_trx_receive_frame or @ref nrf_802154_trx_receive_ack have been started + * when there was no receive buffer set. The RADIO peripheral will start ramping up, but it will remain + * in @c RXIDLE state, because of missing receive buffer. This function allows to check if such situation + * occurred. + * + * Usually this function may be called by buffer management subsystem when buffer becomes available. + * Consider following code snippet: + * @code + * void buffer_is_available_callback(void * p_buffer) + * { + * if (nrf_802154_trx_receive_is_buffer_missing()) + * { + * nrf_802154_trx_receive_buffer_set(p_buffer); + * } + * } + * @endcode + * + * @retval true When in receive mode and receive buffer is missing + * @retval false Otherwise. + */ +bool nrf_802154_trx_receive_is_buffer_missing(void); + +/**@brief Sets pointer to a receive buffer. + * + * @param p_receive_buffer If NULL the next call to @ref nrf_802154_trx_receive_frame or + * @ref nrf_802154_trx_receive_ack will not be able to receive. + * If not NULL it must point to MAX_PACKET_SIZE + 1 (see nrf_802154_const.h) + * buffer where received frame will be stored. + * + * @retval true If operation solved missing buffer condition (see @ref nrf_802154_trx_receive_is_buffer_missing) + * and provided buffer will be used in current receive operation. + * @retval false If operation didn't solve missing buffer condition (either no missing buffer or currently + * not in receive mode). Provided buffer will be used in next receive operation. + */ +bool nrf_802154_trx_receive_buffer_set(void * p_receive_buffer); + +/**@brief Begins frame transmit operation. + * + * This operation performs differently according to cca parameter. + * When cca==false: + * - The RADIO starts ramp up in transmit mode. + * - The RADIO starts sending synchronization header (SHR). + * - @ref nrf_802154_trx_transmit_frame_started handler is called from an ISR just after SHR is sent + * (only when @ref NRF_802154_TX_STARTED_NOTIFY_ENABLED == 1). + * - @ref nrf_802154_trx_transmit_frame_transmitted handler is called from an ISR after full frame is sent on air. + * + * When cca==true: + * - The radio starts ramp up in receive mode, then it starts cca procedure. + * - The @ref nrf_802154_trx_transmit_frame_ccastarted handler is called from an ISR when + * the RADIO started CCA procedure and @p notifications_mask contained + * @ref TRX_TRANSMIT_NOTIFICATION_CCASTARTED flag. + * - If cca succeded (channel was idle): + * - The RADIO switches to transmit mode (disables receive mode, starts ramp up in transmit mode). + * - The RADIO starts sending sending synchronization header (SHR). + * - If @ref TRX_TRANSMIT_NOTIFICATION_CCAIDLE was present in notifications_mask, + * the @ref nrf_802154_trx_transmit_frame_ccaidle is called. + * - @ref nrf_802154_trx_transmit_frame_started handler is called from an ISR just after SHR is sent + * (only when @ref NRF_802154_TX_STARTED_NOTIFY_ENABLED == 1). + * - @ref nrf_802154_trx_transmit_frame_transmitted handler is called from an ISR after full frame is sent on air. + * - If cca failed (channel was busy): + * - The RADIO disables receive mode + * - @ref nrf_802154_trx_transmit_frame_ccabusy from an ISR handler is called + * + * @param p_transmit_buffer Pointer to a buffer containing frame to transmit. + * Must not be NULL. p_transmit_buffer[0] is the number of + * bytes following p_transmit_buffer[0] to send. + * The number of bytes pointed by p_transmit buffer must + * be at least 1 and not less than p_transmit_buffer[0] + 1. + * + * @param cca Selects if CCA procedure should be performed prior to + * real transmission. If false no cca will be performed. + * If true, cca will be performed. + * + * @param notifications_mask Selects additional notifications generated during a frame transmission. + * It is bitwise combination of @ref nrf_802154_trx_transmit_notifications_t values. + * @note To transmit ack after frame is received use @ref nrf_802154_trx_transmit_ack. + */ +void nrf_802154_trx_transmit_frame(const void * p_transmit_buffer, + bool cca, + nrf_802154_trx_transmit_notifications_t notifications_mask); + +/**@brief Puts the trx module into transmit ACK mode. + * + * @note This function may be called from @ref nrf_802154_trx_receive_received handler only. + * This is because in this condition only the TIMER peripheral is running and allows timed transmission. + * + * @param[in] p_transmit_buffer Pointer to a buffer containing ACK frame to be transmitted. + * Caller is responsible for preparing an ACK frame according to the 802.15.4 protocol. + * @param[in] delay_us Delay (in microseconds) + * + * @retval true If the function was called in time and ACK frame is scheduled for transmission. + * When transmission starts and @ref NRF_802154_TX_STARTED_NOTIFY_ENABLED != 0 + * the function @ref nrf_802154_trx_transmit_ack_started will be called. + * When transmission is finished the function @ref nrf_802154_trx_transmit_ack_transmitted + * will be called. + * @retval false If the function was called too late and given delay_us time gap + * between received frame and ACK frame transmission could not be hold. + * The TIMER peripheral is stopped and it is not possible to trigger @ref nrf_802154_trx_transmit_ack + * again without receiving another frame again. No handlers will be called. + */ +bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_us); + +/**@brief Puts trx module into IDLE mode. + * + * @retval true If entering into IDLE mode started, @ref nrf_802154_trx_go_idle_finished will be called + * (if not aborted by call to @ref nrf_802154_trx_abort or nrf_802154_trx_disable). + * @retval false If already in IDLE mode or just requested @ref nrf_802154_trx_go_idle. There will be + * no @ref nrf_802154_trx_go_idle_finished handler being result of this function. + */ +bool nrf_802154_trx_go_idle(void); + +/**@brief Starts standalone cca operation. + * + * Operation ends with a call to @ref nrf_802154_trx_standalone_cca_finished handler from an ISR. + */ +void nrf_802154_trx_standalone_cca(void); + +/**@brief Starts generating continuous carrier. + * + * Generation of a continuous carrier generates no handlers. It may be terminated by a call to + * @ref nrf_802154_trx_abort or @ref nrf_802154_trx_disable. + */ +void nrf_802154_trx_continuous_carrier(void); + +/**@brief Restarts generating continuous carrier + * + * When continuous carrier was being generated and channel change was requested by a call to @ref nrf_802154_trx_channel_set. + * The frequency is not changed automatically. Use @ref nrf_802154_trx_continuous_carrier_restart to + * stop generating continuous carrier on old frequency and start this operation on a new frequency. + * @ref nrf_802154_trx_continuous_carrier_restart is usually faster than + * call to @ref nrf_802154_trx_abort @ref nrf_802154_trx_continuous_carrier + */ +void nrf_802154_trx_continuous_carrier_restart(void); + +/**@brief Starts generating modulated carrier with given buffer. + * + * @param[in] p_transmit_buffer Pointer to a buffer used for modulating the carrier wave. + */ +void nrf_802154_trx_modulated_carrier(const void * p_transmit_buffer); + +/** @brief Restarts generating modulated carrier.*/ +void nrf_802154_trx_modulated_carrier_restart(void); + +/**@brief Puts trx module into energy detection mode. + * + * Operation ends up with a call to @ref nrf_802154_trx_energy_detection_finished handler. + * + * Operation can be terminated with a call to @ref nrf_802154_trx_abort or @ref nrf_802154_trx_disable. + * In this case no handler is called. + * + * @param ed_count Number of iterations to perform. Must be in range 1..2097152. + * One iteration takes 128 microseconds. + */ +void nrf_802154_trx_energy_detection(uint32_t ed_count); + +/**@brief Aborts currently performed operation. + * + * When trx module is in @c DISABLED, @c IDLE or @c FINISHED state, this function has no effect. + * Otherwise current operation is terminated and no handler will be generated by the operation + * regardless of its state. In this case trx module will be in @c FINISHED state allowing + * commencement of a next operation. + */ +void nrf_802154_trx_abort(void); + +/**@brief Gets current state of the TRX module. + * + * @return Current state of the TRX module.*/ +trx_state_t nrf_802154_trx_state_get(void); + +/**@brief Handler called at the beginning of a ACK reception. + * + * This handler is called from an ISR when receive of an ack has been started, and + * the RADIO received synchronization header (SHR). + */ +extern void nrf_802154_trx_receive_ack_started(void); + +/**@brief Handler called at the beginning of frame reception (earliest possible moment). + * + * This handler is called from an ISR when: + * - receive operation has been started with a call to @ref nrf_802154_trx_receive_frame + * - the RADIO peripheral detected energy on channel or started synchronizing to it. + * + * When this handler is called following holds: + * - trx module is in @c RXFRAME state. + * + * Implementation of @ref nrf_802154_trx_receive_frame_started may call: + * - @ref nrf_802154_trx_abort if current receive frame needs to be aborted + * (usually followed by a call moving the trx module out of @c FINISHED state) + * - @ref nrf_802154_trx_disable + * + * @note This handler may be triggered several times during receive of a preamble + * of a frame. It can be followed by call to @ref nrf_802154_trx_receive_frame_started + * (if enabled) and then by @ref nrf_802154_trx_receive_frame_crcok or + * @ref nrf_802154_trx_receive_frame_crcerror, but there is possibility + * that it will not be followed by these calls (In case when the RADIO didn't found + * full preamble.). If implementation of this handler starts some + * activity that must be terminated by a further call, it must implement + * its own timeout feature. + */ +extern void nrf_802154_trx_receive_frame_prestarted(void); + +/**@brief Handler called at the beginning of frame reception. + * + * This handler is called from an ISR when: + * - receive operation has been started with a call to @ref nrf_802154_trx_receive_frame + * - the RADIO started receiving a frame and has just received SHR field of the frame. + * + * When this handler is called following holds: + * - trx module is in @c RXFRAME state. + * + * Implementation of @ref nrf_802154_trx_receive_frame_started may call: + * - @ref nrf_802154_trx_abort if current receive frame needs to be aborted + * (usually followed by a call moving the trx module out of @c FINISHED state) + * - @ref nrf_802154_trx_disable + */ +extern void nrf_802154_trx_receive_frame_started(void); + +/**@brief Handler called during reception of a frame, when given number of bytes is received. + * + * This handler is called from an ISR when given number of bytes (see @ref nrf_802154_trx_receive) + * have been just received. + * + * @note If the handler decides to abort receive by a call to @ref nrf_802154_trx_abort or + * @ref nrf_802154_trx_disable it must return value equal to original bcc parameter passed. + * + * @param[in] bcc Number of bytes that have been already received. + * + * @return Value greater than original value of bcc parameter will cause @ref nrf_802154_trx_receive_frame_bcmatched + * to be called again when further data arrive. Value less than or equal to original bcc value will not cause this + * behavior. + */ +extern uint8_t nrf_802154_trx_receive_frame_bcmatched(uint8_t bcc); + +/**@brief Handler called when a frame is received with correct crc. + * + * This handler is called from an ISR when: + * - receive operation has been started with a call to @ref nrf_802154_trx_receive_frame + * - the RADIO received a frame on air with correct crc + * + * When this handler is called following holds: + * - trx module is in @c RXFRAME_FINISHED state. + * - the RADIO peripheral started ramping down (or it ramped down already) + * - TIMER peripheral started counting allowing @ref nrf_802154_trx_transmit_ack + * + * Implementation of @ref nrf_802154_trx_receive_frame_received is responsible for + * leaving @c RXFRAME_FINISHED state. It may do this by call to: + * - @ref nrf_802154_trx_transmit_ack, + * - @ref nrf_802154_trx_receive_frame, + * - @ref nrf_802154_trx_transmit_frame, + * - @ref nrf_802154_trx_go_idle, + * - @ref nrf_802154_trx_disable. + */ +extern void nrf_802154_trx_receive_frame_received(void); + +/**@brief Handler called when a frame is received with incorrect crc. + * + * This handler is called from an ISR when: + * - receive operation has been started with a call to @ref nrf_802154_trx_receive_frame + * - the RADIO received a frame on air with incorrect crc + * + * If NRF_802154_DISABLE_BCC_MATCHING == 0: + * When this handler is called following holds: + * - the RADIO peripheral started ramping down (or it ramped down already) + * - trx module is in @c FINISHED state. + * + * Implementation of @ref nrf_802154_trx_receive_frame_crcerror is responsible for + * leaving @c FINISHED state. It may do this by call to: + * - @ref nrf_802154_trx_receive_frame, + * - @ref nrf_802154_trx_transmit_frame, + * - @ref nrf_802154_trx_go_idle, + * - @ref nrf_802154_trx_disable. + * + * If NRF_802154_DISABLE_BCC_MATCHING != 0: + * - the RADIO peripheral is restarted automatically (by hardware) in receive mode + * - trx module stays in @c RXFRAME state + * Implementation of @ref nrf_802154_trx_receive_frame_crcerror should not call + * @ref nrf_802154_trx_receive_frame as receive is restarted automatically by the hardware. + * If the implementation wishes to change state it should call + * @ref nrf_802154_trx_abort first. + */ +extern void nrf_802154_trx_receive_frame_crcerror(void); + +/**@brief Handler called when an ack is received with correct crc. + * + * This handler is called from an ISR when: + * - receive ack operation has been started with a call to @ref nrf_802154_trx_receive_ack + * - the RADIO received a frame on air with correct crc + * + * When this handler is called following holds: + * - the RADIO peripheral started ramping down (or it ramped down already) + * - trx module is in @c FINISHED state. + * + * Implementation is responsible for: + * - checking if received frame is an ack and matches previously transmitted frame. + * - leaving @c FINISHED state. It may do this by call to: + * - @ref nrf_802154_trx_receive_frame, + * - @ref nrf_802154_trx_transmit_frame, + * - @ref nrf_802154_trx_go_idle, + * - @ref nrf_802154_trx_disable. + */ +extern void nrf_802154_trx_receive_ack_received(void); + +/**@brief Handler called when an ack is received with incorrect crc. + * + * This handler is called from an ISR when: + * - receive ack operation has been started with a call to @ref nrf_802154_trx_receive_ack + * - the RADIO received a frame on air with incorrect crc + * + * When this handler is called following holds: + * - the RADIO peripheral started ramping down (or it ramped down already) + * - trx module is in @c FINISHED state. + * + * Implementation is responsible for: + * - leaving @c FINISHED state. It may do this by call to: + * - @ref nrf_802154_trx_receive_frame, + * - @ref nrf_802154_trx_transmit_frame, + * - @ref nrf_802154_trx_go_idle, + * - @ref nrf_802154_trx_disable. + */ +extern void nrf_802154_trx_receive_ack_crcerror(void); + +/**@brief Handler called when a cca operation during transmit attempt started. + * + * This handler is called from an ISR when: + * - transmit operation with cca has been started with a call to @ref nrf_802154_transmit_frame(cca=true). + * - transmit operation was started with parameter @c notifications_mask containing + * TRX_TRANSMIT_NOTIFICATION_CCASTARTED + * - the RADIO peripheral started CCA operation. + * + * Implementation is not responsible for anything related to the trx module since it serves as + * a pure notification of the channel assessment started event during transmission. + */ +extern void nrf_802154_trx_transmit_frame_ccastarted(void); + +/**@brief Handler called when a cca operation during transmit attempt was successful. + * + * This handler is called from an ISR when: + * - transmit operation with cca has been started with a call to @ref nrf_802154_transmit_frame(cca=true). + * - the RADIO detected that channel was free. + * + * When this handler is called following holds: + * - the RADIO peripheral started ramping up (or it ramped up already) + * - trx module is in @c TXFRAME state. + * + * Implementation is not responsible for anything since it serves as + * a pure notification of the successful channel assessment during transmission. + */ +extern void nrf_802154_trx_transmit_frame_ccaidle(void); + +/**@brief Handler called when a cca operation during transmit attempt failed. + * + * This handler is called from an ISR when: + * - transmit operation with cca has been started with a call to @ref nrf_802154_transmit_frame(cca=true). + * - the RADIO detected that channel was busy. + * + * When this handler is called following holds: + * - the RADIO peripheral started ramping down (or it ramped down already) + * - trx module is in @c FINISHED state. + * + * Implementation is responsible for: + * - leaving @c FINISHED state. It may do this by call to: + * - @ref nrf_802154_trx_receive_frame, + * - @ref nrf_802154_trx_transmit_frame, + * - @ref nrf_802154_trx_go_idle, + * - @ref nrf_802154_trx_disable. + */ +extern void nrf_802154_trx_transmit_frame_ccabusy(void); + +/**@brief Handler called when frame transmission has just started. + * + * This handler is called from an ISR when: + * - @ref NRF_802154_TX_STARTED_NOTIFY_ENABLED == 1 (see nrf_802154_config.h) + * - transmit operation was started by a call to @ref nrf_802154_trx_transmit_frame. + * - the RADIO peripheral sent synchronization header + * + * When this handler is called following holds: + * - trx module is in @c TXFRAME state + * + * Implementation may (but does not need to) terminate transmission if it wishes by a call to: + * - @ref nrf_802154_trx_abort, + * - @ref nrf_802154_trx_disable. + */ +extern void nrf_802154_trx_transmit_frame_started(void); + +/**@brief Handler called when frame transmission has just been finished. + * + * This handler is called from an ISR when: + * - transmit operation was started by a call to @ref nrf_802154_trx_transmit_frame. + * - the RADIO peripheral sent whole frame on air + * + * When this handler is called following holds: + * - the RADIO peripheral started ramping down (or it ramped down already) + * - trx module is in @c FINISHED state + * + * Implementation is responsible for leaving @c FINISHED state by a call to: + * - @ref nrf_802154_trx_receive_frame, + * - @ref nrf_802154_trx_transmit_frame, + * - @ref nrf_802154_trx_go_idle, + * - @ref nrf_802154_trx_disable. + */ +extern void nrf_802154_trx_transmit_frame_transmitted(void); + +/**@brief Handler called when ack transmission has just been started. + * + * This handler is called from an ISR when: + * - @ref NRF_802154_TX_STARTED_NOTIFY_ENABLED == 1 (see nrf_802154_config.h) + * - transmit operation was started by a call to @ref nrf_802154_trx_transmit_ack. + * - the RADIO peripheral sent synchronization header + * + * When this handler is called following holds: + * - trx module is in @c TXACK state + * + * Implementation may (but does not need to) terminate transmission if it wishes by a call to: + * - @ref nrf_802154_trx_abort, + * - @ref nrf_802154_trx_disable. + */ +extern void nrf_802154_trx_transmit_ack_started(void); + +/**@brief Handler called when ack transmission has just been finished. + * + * This handler is called from an ISR when: + * - transmit operation was started by a call to @ref nrf_802154_trx_transmit_ack. + * - the RADIO peripheral sent whole ack frame on air + * + * When this handler is called following holds: + * - the RADIO peripheral started ramping down (or it ramped down already) + * - trx module is in @c FINISHED state + * + * Implementation is responsible for leaving @c FINISHED state by a call to: + * - @ref nrf_802154_trx_receive_frame, + * - @ref nrf_802154_trx_transmit_frame, + * - @ref nrf_802154_trx_go_idle, + * - @ref nrf_802154_trx_disable. + */ +extern void nrf_802154_trx_transmit_ack_transmitted(void); + +/**@brief Handler called when trx module reached @c IDLE state. + * + * This handler is called from an ISR when: + * - transition to idle state was successfully requested by a call to @ref nrf_802154_trx_go_idle. + * - the RADIO peripheral reached DISABLED state + * - the FEM module has been powered off + * + * When this handler is called following holds: + * - the RADIO is in @c DISABLED state + * - the FEM is powered off + * - trx module is in @c IDLE state + * + * Implementation may leave trx in @c IDLE state or it may request: + * - @ref nrf_802154_trx_receive_frame, + * - @ref nrf_802154_trx_transmit_frame, + * - @ref nrf_802154_trx_disable. + */ +extern void nrf_802154_trx_go_idle_finished(void); + +/**@brief Handler called when standalone cca operaion has been just finished. + * + * This handler is called from an ISR when: + * - standalone cca operation was requested by a call to @ref nrf_802154_trx_standalone_cca + * - the RADIO peripheral finished cca operation + * + * When this handler is called following holds: + * - the RADIO peripheral started ramping down (or it ramped down already) + * - trx module is in @c FINISHED state + * + * Implementation is responsible for leaving @c FINISHED state by a call to: + * - @ref nrf_802154_trx_receive_frame, + * - @ref nrf_802154_trx_transmit_frame, + * - @ref nrf_802154_trx_go_idle, + * - @ref nrf_802154_trx_disable. + * + * @param channel_was_idle Informs implementation of the handler if channel was idle. + * true means the channel was idle, false means the channel was busy. + */ +extern void nrf_802154_trx_standalone_cca_finished(bool channel_was_idle); + +/**@brief Handler called when energy detection operation has been just finished. + * + * This handler is called from an ISR when: + * - energy detection operation was requested by a call to @ref nrf_802154_trx_energy_detection + * - the RADIO peripheral finished the operation + * + * When this handler is called following holds: + * - the RADIO peripheral started ramping down (or it ramped down already) + * - trx module is in @c FINISHED state + * + * Implementation is responsible for leaving @c FINISHED state by a call to: + * - @ref nrf_802154_trx_receive_frame, + * - @ref nrf_802154_trx_transmit_frame, + * - @ref nrf_802154_trx_go_idle, + * - @ref nrf_802154_trx_disable. + * + * @param channel_was_idle Informs implementation of the handler if channel was idle. + * true means the channel was idle, false means the channel was busy. + */ +extern void nrf_802154_trx_energy_detection_finished(uint8_t ed_sample); + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_802154_TRX_H_ */ diff --git a/src/nrf_802154_trx_dppi.c b/src/nrf_802154_trx_dppi.c new file mode 100644 index 0000000..6f7d7ba --- /dev/null +++ b/src/nrf_802154_trx_dppi.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_TRX_PPI + +#include "nrf_802154_trx_ppi_api.h" + +#include "nrf_802154_debug_log.h" +#include "nrf_802154_peripherals.h" + +#include "hal/nrf_dppi.h" +#include "hal/nrf_egu.h" +#include "hal/nrf_radio.h" +#include "hal/nrf_timer.h" + +#define EGU_EVENT NRF_EGU_EVENT_TRIGGERED15 +#define EGU_TASK NRF_EGU_TASK_TRIGGER15 + +#define DPPI_CHGRP_RAMP_UP NRF_DPPI_CHANNEL_GROUP0 ///< PPI group used to disable self-disabling PPIs +#define DPPI_CHGRP_RAMP_UP_DIS_TASK NRF_DPPI_TASK_CHG0_DIS ///< PPI task used to disable self-disabling PPIs + +#define PPI_DISABLED_EGU NRF_802154_DPPI_RADIO_DISABLED_TO_EGU +#define PPI_EGU_RAMP_UP NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP +#define PPI_TIMER_TX_ACK NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN +#define PPI_RADIO_SYNC_EGU_SYNC NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC + +void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task, bool start_timer) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + // Clr event EGU (needed for nrf_802154_trx_ppi_for_ramp_up_was_triggered) + nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT); + + nrf_dppi_channels_include_in_group(NRF_DPPIC, 1UL << PPI_EGU_RAMP_UP, DPPI_CHGRP_RAMP_UP); + nrf_egu_publish_set(NRF_802154_EGU_INSTANCE, EGU_EVENT, PPI_EGU_RAMP_UP); + nrf_radio_subscribe_set(NRF_RADIO, ramp_up_task, PPI_EGU_RAMP_UP); + nrf_dppi_subscribe_set(NRF_DPPIC, DPPI_CHGRP_RAMP_UP_DIS_TASK, PPI_EGU_RAMP_UP); + + if (start_timer) + { + nrf_timer_subscribe_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START, PPI_DISABLED_EGU); + } + + nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, EGU_TASK, PPI_DISABLED_EGU); + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_DISABLED, PPI_DISABLED_EGU); + + nrf_dppi_channels_enable(NRF_DPPIC, + (1UL << PPI_EGU_RAMP_UP) | + (1UL << PPI_DISABLED_EGU)); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool start_timer) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_dppi_channels_disable(NRF_DPPIC, + (1UL << PPI_EGU_RAMP_UP) | + (1UL << PPI_DISABLED_EGU)); + + nrf_egu_publish_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT); + nrf_radio_subscribe_clear(NRF_RADIO, ramp_up_task); + nrf_dppi_subscribe_clear(NRF_DPPIC, DPPI_CHGRP_RAMP_UP_DIS_TASK); + nrf_dppi_channels_remove_from_group(NRF_DPPIC, 1UL << PPI_EGU_RAMP_UP, DPPI_CHGRP_RAMP_UP); + + if (start_timer) + { + nrf_timer_subscribe_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START); + } + + nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, EGU_TASK); + nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait(void) +{ + __ASM("nop"); + __ASM("nop"); + __ASM("nop"); + __ASM("nop"); + __ASM("nop"); + __ASM("nop"); +} + +bool nrf_802154_trx_ppi_for_ramp_up_was_triggered(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + if (nrf_radio_state_get(NRF_RADIO) != NRF_RADIO_STATE_DISABLED) + { + // If RADIO state is not DISABLED, it means that RADIO is still ramping down or already + // started ramping up. + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + return true; + } + + // Wait for PPIs + nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait(); + + if (nrf_egu_event_check(NRF_802154_EGU_INSTANCE, EGU_EVENT)) + { + // If EGU event is set, procedure is running. + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + return true; + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + return false; +} + +void nrf_802154_trx_ppi_for_ack_tx_set(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + // TIMER_COMPARE1 ----> RADIO_TXEN + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, PPI_TIMER_TX_ACK); + nrf_timer_publish_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE1, PPI_TIMER_TX_ACK); + + nrf_dppi_channels_enable(NRF_DPPIC, (1UL << PPI_TIMER_TX_ACK)); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_ack_tx_clear(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_dppi_channels_disable(NRF_DPPIC, (1UL << PPI_TIMER_TX_ACK)); + + nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN); + nrf_timer_publish_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_EVENT_COMPARE1); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_fem_set(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_timer_subscribe_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START, PPI_DISABLED_EGU); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_fem_clear(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_timer_subscribe_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +bool nrf_802154_trx_ppi_for_fem_powerdown_set(NRF_TIMER_Type * p_instance, + uint32_t compare_channel) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + // TODO: Implement this function when FEM API supports nRF53 + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + return false; +} + +void nrf_802154_trx_ppi_for_fem_powerdown_clear(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + // TODO: Implement this function when FEM API supports nRF53 + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +uint32_t nrf_802154_trx_ppi_group_for_abort_get(void) +{ + // TODO: Implement it when external event (like coex) can abort radio operation + return 0; +} + +#if defined(RADIO_INTENSET_SYNC_Msk) +void nrf_802154_trx_ppi_for_radio_sync_set(nrf_egu_task_t task) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_SYNC, PPI_RADIO_SYNC_EGU_SYNC); + nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, task, PPI_RADIO_SYNC_EGU_SYNC); + nrf_dppi_channels_enable(NRF_DPPIC, (1UL << PPI_RADIO_SYNC_EGU_SYNC)); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_radio_sync_clear(nrf_egu_task_t task) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_dppi_channels_disable(NRF_DPPIC, (1UL << PPI_RADIO_SYNC_EGU_SYNC)); + nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_SYNC); + nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, task); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +#endif diff --git a/src/nrf_802154_trx_ppi.c b/src/nrf_802154_trx_ppi.c new file mode 100644 index 0000000..3828233 --- /dev/null +++ b/src/nrf_802154_trx_ppi.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define NRF_802154_MODULE_ID NRF_802154_DRV_MODULE_ID_TRX_PPI + +#include "nrf_802154_trx_ppi_api.h" + +#include + +#include "nrf_802154_debug_log.h" +#include "nrf_802154_peripherals.h" + +#include "hal/nrf_egu.h" +#include "hal/nrf_ppi.h" +#include "hal/nrf_radio.h" +#include "hal/nrf_timer.h" + +#define EGU_EVENT NRF_EGU_EVENT_TRIGGERED15 +#define EGU_TASK NRF_EGU_TASK_TRIGGER15 + +#define PPI_CHGRP_RAMP_UP NRF_802154_PPI_CORE_GROUP ///< PPI group used to disable self-disabling PPIs +#define PPI_CHGRP_RAMP_UP_DIS_TASK NRF_PPI_TASK_CHG0_DIS ///< PPI task used to disable self-disabling PPIs + +#define PPI_CHGRP_ABORT NRF_802154_PPI_ABORT_GROUP ///< PPI group used to disable PPIs when async event aborting radio operation is propagated through the system + +#define PPI_DISABLED_EGU NRF_802154_PPI_RADIO_DISABLED_TO_EGU ///< PPI that connects RADIO DISABLED event with EGU task +#define PPI_EGU_RAMP_UP NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP ///< PPI that connects EGU event with RADIO TXEN or RXEN task +#define PPI_EGU_TIMER_START NRF_802154_PPI_EGU_TO_TIMER_START ///< PPI that connects EGU event with TIMER START task +#define PPI_TIMER_TX_ACK NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN ///< PPI that connects TIMER COMPARE event with RADIO TXEN task +#define PPI_RADIO_SYNC_EGU_SYNC NRF_802154_PPI_RADIO_SYNC_TO_EGU_SYNC ///< PPI that connects RADIO SYNC event with EGU task for SYNC channel + +void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task, bool start_timer) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + // Clr event EGU (needed for nrf_802154_trx_ppi_for_ramp_up_was_triggered) + nrf_egu_event_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT); + + nrf_ppi_channel_and_fork_endpoint_setup(NRF_PPI, PPI_EGU_RAMP_UP, + nrf_egu_event_address_get( + NRF_802154_EGU_INSTANCE, + EGU_EVENT), + nrf_radio_task_address_get(NRF_RADIO, ramp_up_task), + nrf_ppi_task_address_get(NRF_PPI, + PPI_CHGRP_RAMP_UP_DIS_TASK)); + + if (start_timer) + { + nrf_ppi_channel_endpoint_setup(NRF_PPI, PPI_EGU_TIMER_START, + nrf_egu_event_address_get(NRF_802154_EGU_INSTANCE, + EGU_EVENT), + nrf_timer_task_address_get(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_TASK_START)); + } + + nrf_ppi_channel_endpoint_setup(NRF_PPI, + PPI_DISABLED_EGU, + nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_DISABLED), + nrf_egu_task_address_get(NRF_802154_EGU_INSTANCE, EGU_TASK)); + + nrf_ppi_channel_include_in_group(NRF_PPI, PPI_EGU_RAMP_UP, PPI_CHGRP_RAMP_UP); + + uint32_t ppi_mask = (1UL << PPI_EGU_RAMP_UP) | + (1UL << PPI_DISABLED_EGU); + + if (start_timer) + { + ppi_mask |= (1UL << PPI_EGU_TIMER_START); + } + + nrf_ppi_channels_enable(NRF_PPI, ppi_mask); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool start_timer) +{ + (void)ramp_up_task; + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + uint32_t ppi_mask = (1UL << PPI_EGU_RAMP_UP) | + (1UL << PPI_DISABLED_EGU); + + if (start_timer) + { + ppi_mask |= (1UL << PPI_EGU_TIMER_START); + } + + nrf_ppi_channels_disable(NRF_PPI, ppi_mask); + + nrf_ppi_channel_and_fork_endpoint_setup(NRF_PPI, PPI_EGU_RAMP_UP, 0, 0, 0); + nrf_ppi_channel_endpoint_setup(NRF_PPI, PPI_DISABLED_EGU, 0, 0); + + if (start_timer) + { + nrf_ppi_channel_endpoint_setup(NRF_PPI, PPI_EGU_TIMER_START, 0, 0); + } + + nrf_ppi_channel_remove_from_group(NRF_PPI, PPI_EGU_RAMP_UP, PPI_CHGRP_RAMP_UP); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait(void) +{ + __ASM("nop"); + __ASM("nop"); + __ASM("nop"); + __ASM("nop"); + __ASM("nop"); + __ASM("nop"); +} + +bool nrf_802154_trx_ppi_for_ramp_up_was_triggered(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + if (nrf_radio_state_get(NRF_RADIO) != NRF_RADIO_STATE_DISABLED) + { + // If RADIO state is not DISABLED, it means that RADIO is still ramping down or already + // started ramping up. + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + return true; + } + + // Wait for PPIs + nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait(); + + if (nrf_egu_event_check(NRF_802154_EGU_INSTANCE, EGU_EVENT)) + { + // If EGU event is set, procedure is running. + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + return true; + } + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + return false; +} + +void nrf_802154_trx_ppi_for_ack_tx_set(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_ppi_channel_endpoint_setup(NRF_PPI, + PPI_TIMER_TX_ACK, + nrf_timer_event_address_get(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_EVENT_COMPARE1), + nrf_radio_task_address_get(NRF_RADIO, + NRF_RADIO_TASK_TXEN)); + nrf_ppi_channel_enable(NRF_PPI, PPI_TIMER_TX_ACK); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_ack_tx_clear(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_ppi_channel_disable(NRF_PPI, PPI_TIMER_TX_ACK); + nrf_ppi_channel_endpoint_setup(NRF_PPI, PPI_TIMER_TX_ACK, 0, 0); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_fem_set(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + uint32_t event_addr = nrf_egu_event_address_get(NRF_802154_EGU_INSTANCE, + EGU_EVENT); + uint32_t task_addr = nrf_timer_task_address_get(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_TASK_START); + + nrf_ppi_channel_endpoint_setup(NRF_PPI, PPI_EGU_TIMER_START, event_addr, task_addr); + nrf_ppi_channel_enable(NRF_PPI, PPI_EGU_TIMER_START); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_fem_clear(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_ppi_channel_disable(NRF_PPI, PPI_EGU_TIMER_START); + nrf_ppi_channel_endpoint_setup(NRF_PPI, PPI_EGU_TIMER_START, 0, 0); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +bool nrf_802154_trx_ppi_for_fem_powerdown_set(NRF_TIMER_Type * p_instance, + uint32_t compare_channel) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + // PPI_EGU_TIMER_START is reused here on purpose, to save resources, + // as fem powerdown cannot be scheduled simultaneously with fem ramp-up. + bool result = nrf_fem_prepare_powerdown(p_instance, compare_channel, PPI_EGU_TIMER_START); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); + + return result; +} + +void nrf_802154_trx_ppi_for_fem_powerdown_clear(void) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_ppi_channel_disable(NRF_PPI, PPI_EGU_TIMER_START); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +uint32_t nrf_802154_trx_ppi_group_for_abort_get(void) +{ + return (uint32_t)PPI_CHGRP_ABORT; +} + +#if defined(RADIO_INTENSET_SYNC_Msk) +void nrf_802154_trx_ppi_for_radio_sync_set(nrf_egu_task_t task) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_ppi_channel_endpoint_setup(NRF_PPI, + PPI_RADIO_SYNC_EGU_SYNC, + nrf_radio_event_address_get(NRF_RADIO, NRF_RADIO_EVENT_SYNC), + nrf_egu_task_address_get(NRF_802154_EGU_INSTANCE, task)); + nrf_ppi_channel_enable(NRF_PPI, PPI_RADIO_SYNC_EGU_SYNC); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +void nrf_802154_trx_ppi_for_radio_sync_clear(nrf_egu_task_t task) +{ + (void)task; + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_ppi_channel_disable(NRF_PPI, PPI_RADIO_SYNC_EGU_SYNC); + nrf_ppi_channel_endpoint_setup(NRF_PPI, PPI_RADIO_SYNC_EGU_SYNC, 0, 0); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + +#endif diff --git a/src/nrf_802154_trx_ppi_api.h b/src/nrf_802154_trx_ppi_api.h new file mode 100644 index 0000000..c7ea559 --- /dev/null +++ b/src/nrf_802154_trx_ppi_api.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2020, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Module that contains PPI management functions for + * the nRF IEEE 802.15.4 radio driver. + */ + +#ifndef NRF_802154_TRX_PPI_H_ +#define NRF_802154_TRX_PPI_H_ + +#include +#include + +#include "hal/nrf_egu.h" +#include "hal/nrf_radio.h" + +/** + * @brief Set PPIs to connect RADIO DISABLED event with tasks needed to ramp up. + * + * Connections created by this function in DPPI variant: + * + * RADIO_DISABLED ----> EGU -----> ramp_up_task + * | \--> self disable + * if (start_timer) + * \-------------> TIMER_START + * + * Connections created by this function in PPI variant: + * + * RADIO_DISABLED ----> EGU -----> ramp_up_task + * \--> self disable + * + * EGU ---> if (start_timer) ----> TIMER_START + * + * @param[in] ramp_up_task Task triggered to start ramp up procedure. + * @param[in] start_timer If timer is to be started on RADIO DISABLED event. + */ +void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ramp_up_task, bool start_timer); + +/** + * @brief Clear PPIs to connect RADIO DISABLED event with tasks needed to ramp up. + * + * @param[in] ramp_up_task Task triggered to start ramp up procedure. + * @param[in] start_timer If timer start on RADIO DISABLED event is to be deconfigured as well. See @ref nrf_802154_trx_ppi_for_ramp_up_set. + */ +void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool start_timer); + +/** + * @brief Wait until PPIs configured to ramp up radio are propagated through PPI system. + * + * During detection if trigger of DISABLED event caused start of hardware procedure, detecting + * function needs to wait until event is propagated from RADIO through PPI to EGU. This delay is + * required to make sure EGU event is set if hardware was prepared before DISABLED event was + * triggered. + */ +void nrf_802154_trx_ppi_for_ramp_up_propagation_delay_wait(void); + +/** + * @brief Detect if PPIs configured to start radio operation were triggered. + * + * Radio ramp up starts by design from RADIO DISABLED event. This functions verifies this event + * and PPIs status. + * + * @retval true PPIs were triggered. + * @retval false PPIs were not triggered. To trigger them, the caller must trigger RADIO DISABLE task. + */ +bool nrf_802154_trx_ppi_for_ramp_up_was_triggered(void); + +/** + * @brief Set PPIs to connect TIMER event with radio TXEN task, needed to ramp up for ACK TX. + */ +void nrf_802154_trx_ppi_for_ack_tx_set(void); + +/** + * @brief Clear PPIs to connect TIMER event with radio TXEN task, needed to ramp up for ACK TX. See @ref void nrf_802154_trx_ppi_for_ack_tx_set + */ +void nrf_802154_trx_ppi_for_ack_tx_clear(void); + +/** + * @brief Configure PPIs needed for external LNA or PA. Radio DISABLED event will be connected to timer START task. + * As a result, FEM ramp-up will be scheduled during the radio ramp-up period, with timing based on FEM implementation used. + */ +void nrf_802154_trx_ppi_for_fem_set(void); + +/** + * @brief Deconfigure PPIs needed for external LNA or PA. See @ref nrf_802154_trx_ppi_for_fem_set + */ +void nrf_802154_trx_ppi_for_fem_clear(void); + +/** + * @brief Prepare FEM to enter powerdown state. + * + * @param[in] p_instance Timer instance that is used to schedule the transition to the Power Down state. + * @param[in] compare_channel Compare channel to hold a value for the timer. + * + * @note This function and @ref nrf_802154_trx_ppi_for_fem_powerdown_clear looks not symetrical. + * It seems it could be better designed. We shall refactor it when porting FEM support to + * nRF53 family. + * + * @retval true FEM powerdown procedure has started. + * @retval false FEM powerdown procedure is not needed. + */ +bool nrf_802154_trx_ppi_for_fem_powerdown_set(NRF_TIMER_Type * p_instance, + uint32_t compare_channel); + +/** + * @brief Unconfigure PPIs needed to enter the powerdown state by FEM. + */ +void nrf_802154_trx_ppi_for_fem_powerdown_clear(void); + +/** + * @brief Get PPI group id used for disabling radio operations by an external event. + */ +uint32_t nrf_802154_trx_ppi_group_for_abort_get(void); + +/** + * @brief Configure PPIs needed to trigger IRQ from RADIO event SYNC. + * + * @param[in] task EGU task used for triggering IRQ on radio SYNC event. + */ +void nrf_802154_trx_ppi_for_radio_sync_set(nrf_egu_task_t task); + +/** + * @brief Unconfigure PPIs needed to trigger IRQ from RADIO event SYNC. + * + * @param[in] task EGU task used for triggering IRQ on radio SYNC event. See @ref nrf_802154_trx_ppi_for_radio_sync_set + */ +void nrf_802154_trx_ppi_for_radio_sync_clear(nrf_egu_task_t task); + +#endif /* NRF_802154_TRX_PPI_H_ */ diff --git a/src/nrf_802154_types.h b/src/nrf_802154_types.h index 202c346..aca99db 100644 --- a/src/nrf_802154_types.h +++ b/src/nrf_802154_types.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_TYPES_H__ @@ -33,7 +34,15 @@ #include -#include "nrf_radio.h" +/** + * Avoid including nrfx dependencies in a unit test build. + */ +#if !defined(UNIT_TEST) + #include "hal/nrf_radio.h" +#else +typedef uint8_t nrf_radio_cca_mode_t; + +#endif /** * @defgroup nrf_802154_types Type definitions used in the 802.15.4 driver @@ -54,6 +63,7 @@ typedef uint8_t nrf_802154_state_t; #define NRF_802154_STATE_ENERGY_DETECTION 0x05 // !< Radio in the energy detection state. #define NRF_802154_STATE_CCA 0x06 // !< Radio in the CCA state. #define NRF_802154_STATE_CONTINUOUS_CARRIER 0x07 // !< Radio in the continuous carrier state. +#define NRF_802154_STATE_MODULATED_CARRIER 0x08 // !< Radio in the modulated carrier state. /** * @brief Errors reported during the frame transmission. @@ -125,9 +135,9 @@ typedef uint8_t nrf_802154_term_t; typedef struct { nrf_radio_cca_mode_t mode; // !< CCA mode. - uint8_t ed_threshold; // !< Busy threshold of the CCA energy. Not used in NRF_RADIO_CCA_MODE_CARRIER. - uint8_t corr_threshold; // !< Busy threshold of the CCA correlator. Not used in NRF_RADIO_CCA_MODE_ED. - uint8_t corr_limit; // !< Limit of occurrences above the busy threshold of the CCA correlator. Not used in NRF_RADIO_CCA_MODE_ED. + uint8_t ed_threshold; // !< Busy threshold of the CCA energy. Not used in @ref NRF_RADIO_CCA_MODE_CARRIER. + uint8_t corr_threshold; // !< Busy threshold of the CCA correlator. Not used in @ref NRF_RADIO_CCA_MODE_ED. + uint8_t corr_limit; // !< Limit of occurrences above the busy threshold of the CCA correlator. Not used in @ref NRF_RADIO_CCA_MODE_ED. } nrf_802154_cca_cfg_t; /** @@ -161,6 +171,119 @@ typedef uint8_t nrf_802154_src_addr_match_t; #define NRF_802154_RSSI_INVALID INT8_MAX +/** + * @brief Mode of triggering receive request to Coex arbiter. + * + * Possible values: + * - @ref NRF_802154_COEX_RX_REQUEST_MODE_ENERGY_DETECTION, + * - @ref NRF_802154_COEX_RX_REQUEST_MODE_PREAMBLE, + * - @ref NRF_802154_COEX_RX_REQUEST_MODE_DESTINED + */ +typedef uint8_t nrf_802154_coex_rx_request_mode_t; + +#define NRF_802154_COEX_RX_REQUEST_MODE_ENERGY_DETECTION 0x01 // !< Coex requests to arbiter in receive mode upon energy detected. +#define NRF_802154_COEX_RX_REQUEST_MODE_PREAMBLE 0x02 // !< Coex requests to arbiter in receive mode upon preamble reception. +#define NRF_802154_COEX_RX_REQUEST_MODE_DESTINED 0x03 // !< Coex requests to arbiter in receive mode upon detection that frame is addressed to this device. + +/** + * @brief Mode of triggering transmit request to Coex arbiter. + * + * Possible values: + * - @ref NRF_802154_COEX_TX_REQUEST_MODE_FRAME_READY, + * - @ref NRF_802154_COEX_TX_REQUEST_MODE_CCA_START, + * - @ref NRF_802154_COEX_TX_REQUEST_MODE_CCA_DONE + */ +typedef uint8_t nrf_802154_coex_tx_request_mode_t; + +#define NRF_802154_COEX_TX_REQUEST_MODE_FRAME_READY 0x01 // !< Coex requests to arbiter in transmit mode when the frame is ready to be transmitted. +#define NRF_802154_COEX_TX_REQUEST_MODE_CCA_START 0x02 // !< Coex requests to arbiter in transmit mode before CCA is started. +#define NRF_802154_COEX_TX_REQUEST_MODE_CCA_DONE 0x03 // !< Coex requests to arbiter in transmit mode after CCA is finished. + +/** + * @brief Mode of handling Interframe spacing. + * + * Possible values: + * - @ref NRF_802154_IFS_MODE_DISABLED, + * - @ref NRF_802154_IFS_MODE_MATCHING_ADDRESSES, + * - @ref NRF_802154_IFS_MODE_ALWAYS + */ +typedef uint8_t nrf_802154_ifs_mode_t; + +#define NRF_802154_IFS_MODE_DISABLED 0x00 // !< Interframe spacing is never inserted. +#define NRF_802154_IFS_MODE_MATCHING_ADDRESSES 0x01 // !< Interframe spacing is inserted only on matching addresses. +#define NRF_802154_IFS_MODE_ALWAYS 0x02 // !< Interframe spacing is always inserted. + +/** + * @brief Type of structure holding statistic counters. + * + * This structure holds counters of @c uint32_t type only. + */ +typedef struct +{ + /**@brief Number of failed CCA attempts. */ + uint32_t cca_failed_attempts; + /**@brief Number of frames received with correct CRC and with filtering passing. */ + uint32_t received_frames; + /**@brief Number of times energy was detected in receive mode.*/ + uint32_t received_energy_events; + /**@brief Number of times a preamble was received in receive mode. */ + uint32_t received_preambles; + /**@brief Number of coex requests issued to coex arbiter. */ + uint32_t coex_requests; + /**@brief Number of coex requests issued to coex arbiter that have been granted. */ + uint32_t coex_granted_requests; + /**@brief Number of coex requests issued to coex arbiter that have been denied. */ + uint32_t coex_denied_requests; + /**@brief Number of coex grant activations that have been not requested. */ + uint32_t coex_unsolicited_grants; +} nrf_802154_stat_counters_t; + +/** + * @brief Type of structure holding time stamps of certain events. + */ +typedef struct +{ + /**@brief Time stamp of last CSMA/CA procedure started. */ + uint32_t last_csmaca_start_timestamp; + /**@brief Time stamp of last CCA start attempt. */ + uint32_t last_cca_start_timestamp; + /**@brief Time stamp of last CCA attempt finished with CCA IDLE (channel was free to transmit). */ + uint32_t last_cca_idle_timestamp; + /**@brief Time stamp when last bit of transmitted frame was sent on the air. */ + uint32_t last_tx_end_timestamp; + /**@brief Time stamp when last bit of acknowledge frame was received */ + uint32_t last_ack_end_timestamp; + /**@brief Time stamp when last bit of received frame was received. */ + uint32_t last_rx_end_timestamp; +} nrf_802154_stat_timestamps_t; + +/** + * @brief Type of structure holding total times spent in certain states. + * + * This structure holds fields of @c uint64_t type only. + */ +typedef struct +{ + /**@brief Total time in microseconds spent with receiver turned on, but not actually receiving any frames. */ + uint64_t total_listening_time; + /**@brief Total time in microseconds spent with receiver turned on and actually receiving frames. */ + uint64_t total_receive_time; + /**@brief Total time in microseconds spent on transmission. */ + uint64_t total_transmit_time; +} nrf_802154_stat_totals_t; + +/** + * @brief Type of structure holding statistics about the Radio Driver behavior. + */ +typedef struct +{ + /**@brief Statistic counters */ + nrf_802154_stat_counters_t counters; + + /**@brief Time stamps of events */ + nrf_802154_stat_timestamps_t timestamps; +} nrf_802154_stats_t; + /** *@} **/ diff --git a/src/nrf_802154_utils.h b/src/nrf_802154_utils.h index 53b4c0a..12ae0d6 100644 --- a/src/nrf_802154_utils.h +++ b/src/nrf_802154_utils.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef NRF_802154_UTILS_H__ @@ -34,6 +35,8 @@ #include #include #include "nrf.h" +#include +#include /** * @defgroup nrf_802154_utils Utils definitions used in the 802.15.4 driver @@ -67,10 +70,60 @@ * * @param[in] X Array. */ -#define NUMELTS(X) (sizeof((X)) / sizeof(X[0])) +#define NUMELTS(X) (sizeof((X)) / sizeof(X[0])) /**@brief Wait procedure used in a busy loop. */ -#define nrf_802154_busy_wait() __WFE() +#define nrf_802154_busy_wait() __WFE() + +/**@brief Active waiting for given number of microseconds. + * + * It is guaranteed that execution of this macro will take at least @c time_in_us + * number of microseconds. + */ +#define nrf_802154_delay_us(time_in_us) nrfx_coredep_delay_us(time_in_us) + +/**@brief Type holding MCU critical section state. + * + * Variable of this type is required to hold state saved by @ref nrf_802154_mcu_critical_enter + * and restored by @ref nrf_802154_mcu_critical_exit. + */ +typedef uint32_t nrf_802154_mcu_critical_state_t; + +/**@brief Enters critical section on MCU level. + * + * Use @ref nrf_802154_mcu_critical_exit complementary. Consider following code: + * @code + * nrf_802154_mcu_critical_state_t mcu_cs; + * nrf_802154_mcu_critical_enter(mcu_cs); + * // do your critical stuff as fast as possible + * nrf_802154_mcu_critical_exit(mcu_cs); + * @endcode + * + * @param mcu_critical_state Variable of @ref nrf_802154_mcu_critical_state_t where current + * state of MCU level critical section will be stored. + */ +#define nrf_802154_mcu_critical_enter(mcu_critical_state) \ + do \ + { \ + (mcu_critical_state) = __get_PRIMASK(); \ + __disable_irq(); \ + } \ + while (0) + +/**@brief Exits critical section on MCU level. + * + * This shall be used complementary to @ref nrf_802154_mcu_critical_enter. + * + * @param mcu_critical_state Variable of @ref nrf_802154_mcu_critical_state_t where + * state of MCU level critical section is stored by + * former call to @ref nrf_802154_mcu_critical_enter + */ +#define nrf_802154_mcu_critical_exit(mcu_critical_state) \ + do \ + { \ + __set_PRIMASK(mcu_critical_state); \ + } \ + while (0) static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time) { diff --git a/src/platform/clock/nrf_802154_clock_nodrv.c b/src/platform/clock/nrf_802154_clock_nodrv.c deleted file mode 100644 index caff9d6..0000000 --- a/src/platform/clock/nrf_802154_clock_nodrv.c +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements the nrf 802.15.4 Clock Abstraction Layer without any driver. - * - * This implementation uses directly CLOCK hardware registers. - */ - -#include "nrf_802154_clock.h" - -#include -#include - -#include "nrf_802154_config.h" -#include "nrf_802154_utils.h" -#include "platform/irq/nrf_802154_irq.h" - -static void power_clock_irq_handler(void) -{ - if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED)) - { - nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); - - nrf_802154_clock_hfclk_ready(); - } - - if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED)) - { - nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); - - nrf_802154_clock_lfclk_ready(); - } -} - -void nrf_802154_clock_init(void) -{ - nrf_clock_lf_src_set(NRF_802154_CLOCK_LFCLK_SOURCE); - -#if !NRF_802154_IRQ_PRIORITY_ALLOWED(NRF_802154_CLOCK_IRQ_PRIORITY) -#error NRF_802154_CLOCK_IRQ_PRIORITY value out of the allowed range. -#endif - nrf_802154_irq_init(POWER_CLOCK_IRQn, NRF_802154_CLOCK_IRQ_PRIORITY, power_clock_irq_handler); - nrf_802154_irq_enable(POWER_CLOCK_IRQn); - - nrf_clock_int_enable(NRF_CLOCK_INT_HF_STARTED_MASK); - nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK); -} - -void nrf_802154_clock_deinit(void) -{ - nrf_802154_irq_disable(POWER_CLOCK_IRQn); - nrf_802154_irq_clear_pending(POWER_CLOCK_IRQn) - - nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK); - nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK); -} - -void nrf_802154_clock_hfclk_start(void) -{ - nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); - nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); -} - -void nrf_802154_clock_hfclk_stop(void) -{ - nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); -} - -bool nrf_802154_clock_hfclk_is_running(void) -{ - return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); -} - -void nrf_802154_clock_lfclk_start(void) -{ - nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); - nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART); -} - -void nrf_802154_clock_lfclk_stop(void) -{ - nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTOP); -} - -bool nrf_802154_clock_lfclk_is_running(void) -{ - return nrf_clock_lf_is_running(); -} - -__WEAK void nrf_802154_clock_hfclk_ready(void) -{ - // Intentionally empty. -} - -__WEAK void nrf_802154_clock_lfclk_ready(void) -{ - // Intentionally empty. -} - -void POWER_CLOCK_IRQHandler(void) -{ - power_clock_irq_handler(); -} diff --git a/src/platform/clock/nrf_802154_clock_sdk.c b/src/platform/clock/nrf_802154_clock_sdk.c deleted file mode 100644 index de1173f..0000000 --- a/src/platform/clock/nrf_802154_clock_sdk.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements the nrf 802.15.4 HF Clock abstraction with SDK driver. - * - * This implementation uses clock driver implementation from SDK. - */ - -#include "nrf_802154_clock.h" - -#include - -#include -#include - -static void clock_handler(nrf_drv_clock_evt_type_t event); - -static nrf_drv_clock_handler_item_t m_clock_handler = -{ - .p_next = NULL, - .event_handler = clock_handler, -}; - -static void clock_handler(nrf_drv_clock_evt_type_t event) -{ - if (event == NRF_DRV_CLOCK_EVT_HFCLK_STARTED) - { - nrf_802154_clock_hfclk_ready(); - } - - if (event == NRF_DRV_CLOCK_EVT_LFCLK_STARTED) - { - nrf_802154_clock_lfclk_ready(); - } -} - -void nrf_802154_clock_init(void) -{ - nrf_drv_clock_init(); -} - -void nrf_802154_clock_deinit(void) -{ - nrf_drv_clock_uninit(); -} - -void nrf_802154_clock_hfclk_start(void) -{ - nrf_drv_clock_hfclk_request(&m_clock_handler); -} - -void nrf_802154_clock_hfclk_stop(void) -{ - nrf_drv_clock_hfclk_release(); -} - -bool nrf_802154_clock_hfclk_is_running(void) -{ - return nrf_drv_clock_hfclk_is_running(); -} - -void nrf_802154_clock_lfclk_start(void) -{ - nrf_drv_clock_lfclk_request(&m_clock_handler); -} - -void nrf_802154_clock_lfclk_stop(void) -{ - nrf_drv_clock_lfclk_release(); -} - -bool nrf_802154_clock_lfclk_is_running(void) -{ - return nrf_drv_clock_lfclk_is_running(); -} - -__WEAK void nrf_802154_clock_hfclk_ready(void) -{ - // Intentionally empty. -} - -__WEAK void nrf_802154_clock_lfclk_ready(void) -{ - // Intentionally empty. -} diff --git a/src/platform/clock/nrf_802154_clock_zephyr.c b/src/platform/clock/nrf_802154_clock_zephyr.c deleted file mode 100644 index 8ff4dcd..0000000 --- a/src/platform/clock/nrf_802154_clock_zephyr.c +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (c) 2019, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements the nrf 802.15.4 HF Clock abstraction with Zephyr API. - * - * This implementation uses Zephyr API for clock management. - */ - -#include "nrf_802154_clock.h" - -#include - -#include -#include -#include - -static bool hfclk_is_running; -static bool lfclk_is_running; - -void nrf_802154_clock_init(void) -{ - /* Intentionally empty. */ -} - -void nrf_802154_clock_deinit(void) -{ - /* Intentionally empty. */ -} - -static void hfclk_on_callback(struct onoff_manager *mgr, - struct onoff_client *cli, - uint32_t state, - int res) -{ - hfclk_is_running = true; - nrf_802154_clock_hfclk_ready(); -} - -void nrf_802154_clock_hfclk_start(void) -{ - int ret; - static struct onoff_client cli; - struct onoff_manager *mgr = - z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF); - __ASSERT_NO_MSG(mgr != NULL); - - sys_notify_init_callback(&cli.notify, hfclk_on_callback); - - ret = onoff_request(mgr, &cli); - __ASSERT_NO_MSG(ret >= 0); -} - -void nrf_802154_clock_hfclk_stop(void) -{ - int ret; - struct onoff_manager *mgr = - z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF); - __ASSERT_NO_MSG(mgr != NULL); - - hfclk_is_running = false; - - ret = onoff_release(mgr); - __ASSERT_NO_MSG(ret >= 0); -} - -bool nrf_802154_clock_hfclk_is_running(void) -{ - return hfclk_is_running; -} - -static void lfclk_on_callback(struct onoff_manager *mgr, - struct onoff_client *cli, - uint32_t state, - int res) -{ - lfclk_is_running = true; - nrf_802154_clock_lfclk_ready(); -} - -void nrf_802154_clock_lfclk_start(void) -{ - int ret; - static struct onoff_client cli; - struct onoff_manager *mgr = - z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF); - __ASSERT_NO_MSG(mgr != NULL); - - sys_notify_init_callback(&cli.notify, lfclk_on_callback); - - ret = onoff_request(mgr, &cli); - __ASSERT_NO_MSG(ret >= 0); -} - -void nrf_802154_clock_lfclk_stop(void) -{ - int ret; - struct onoff_manager *mgr = - z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_LF); - __ASSERT_NO_MSG(mgr != NULL); - - lfclk_is_running = false; - - ret = onoff_release(mgr); - __ASSERT_NO_MSG(ret >= 0); -} - -bool nrf_802154_clock_lfclk_is_running(void) -{ - return lfclk_is_running; -} - -__WEAK void nrf_802154_clock_hfclk_ready(void) -{ - /* Intentionally empty. */ -} - -__WEAK void nrf_802154_clock_lfclk_ready(void) -{ - /* Intentionally empty. */ -} diff --git a/src/platform/coex/nrf_802154_wifi_coex.h b/src/platform/coex/nrf_802154_wifi_coex.h deleted file mode 100644 index 61b5f78..0000000 --- a/src/platform/coex/nrf_802154_wifi_coex.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @brief Module that defines the Wi-Fi coexistence module. - * - */ - -#ifndef NRF_802154_WIFI_COEX_H_ -#define NRF_802154_WIFI_COEX_H_ - -#include "rsch/nrf_802154_rsch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup nrf_wifi_coex Wi-Fi Coexistence - * @{ - * @ingroup nrf_802154 - * @brief The Wi-Fi Coexistence module. - * - * The Wi-Fi Coexistence module is a client of the PTA (defined in the 802.15.2). It manages GPIO - * to assert pins and respond to pin state changes. - */ - -/** - * @brief Initializes the Wi-Fi Coexistence module. - * - * @note This function must be called once, before any other function from this module. - * - */ -void nrf_802154_wifi_coex_init(void); - -/** - * @brief Deinitializes the Wi-Fi Coexistence module. - * - */ -void nrf_802154_wifi_coex_uninit(void); - -/** - * @brief Requests the given priority from the Wi-Fi Coexistence module. - * - * @note The approval of the requested priority is notified asynchronously by the - * @ref nrf_802154_wifi_coex_prio_changed call. - * - * @param[in] priority The requested priority level. - * - */ -void nrf_802154_wifi_coex_prio_request(rsch_prio_t priority); - -/** - * @brief Gets the priority denial event address. - * - * Get the address of a hardware event that notifies about the denial of a previously approved - * priority. - * - * @returns Address of the priority denial event. - */ -void * nrf_802154_wifi_coex_deny_event_addr_get(void); - -/** - * @brief Notifies about the approved priority change. - * - * The Wi-Fi Coexistence module calls this function to notify the RSCH of the currently approved - * priority level. - * - * @param[in] priority The approved priority level. - */ -extern void nrf_802154_wifi_coex_prio_changed(rsch_prio_t priority); - -/** - *@} - **/ - -#ifdef __cplusplus -} -#endif - -#endif /* NRF_802154_WIFI_COEX_H_ */ diff --git a/src/platform/coex/nrf_802154_wifi_coex_none.c b/src/platform/coex/nrf_802154_wifi_coex_none.c deleted file mode 100644 index 2158617..0000000 --- a/src/platform/coex/nrf_802154_wifi_coex_none.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements the nrf 802.15.4 WiFi Coexitstence abstraction in case no implementation is used. - * - */ - -#include "nrf_802154_wifi_coex.h" - -#include "stddef.h" - -#include - -void nrf_802154_wifi_coex_init(void) -{ - // Intentionally empty -} - -void nrf_802154_wifi_coex_uninit(void) -{ - // Intentionally empty -} - -void nrf_802154_wifi_coex_prio_request(rsch_prio_t priority) -{ - (void)priority; - // Intentionally empty -} - -void * nrf_802154_wifi_coex_deny_event_addr_get(void) -{ - // Intentionally empty - return NULL; -} - -__WEAK void nrf_802154_wifi_coex_prio_changed(rsch_prio_t priority) -{ - (void)priority; - // Intentionally empty -} diff --git a/src/platform/lp_timer/nrf_802154_lp_timer_none.c b/src/platform/lp_timer/nrf_802154_lp_timer_none.c deleted file mode 100644 index 7dd2937..0000000 --- a/src/platform/lp_timer/nrf_802154_lp_timer_none.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements the nrf 802.15.4 timer abstraction in case timer is not used. - * - * This timer abstraction should be used only when none of driver features that use timer is enabled. - * - */ - -#include "nrf_802154_lp_timer.h" - -void nrf_802154_lp_timer_init(void) -{ - // Intentionally empty -} - -void nrf_802154_lp_timer_deinit(void) -{ - // Intentionally empty -} - -void nrf_802154_lp_timer_critical_section_enter(void) -{ - // Intentionally empty -} - -void nrf_802154_lp_timer_critical_section_exit(void) -{ - // Intentionally empty -} - -// Other functions from TimAL API are intentionally not implemented to detect build configuration -// problems compile-time. diff --git a/src/platform/random/nrf_802154_random.h b/src/platform/random/nrf_802154_random.h index 15e8d94..18e800e 100644 --- a/src/platform/random/nrf_802154_random.h +++ b/src/platform/random/nrf_802154_random.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/platform/random/nrf_802154_random_newlib.c b/src/platform/random/nrf_802154_random_newlib.c index 597d7e4..3a0004c 100644 --- a/src/platform/random/nrf_802154_random_newlib.c +++ b/src/platform/random/nrf_802154_random_newlib.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -46,7 +47,20 @@ #include "nrf.h" #if RAAL_SOFTDEVICE + +#if defined (__GNUC__) +_Pragma("GCC diagnostic push") +_Pragma("GCC diagnostic ignored \"-Wreturn-type\"") +_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") +_Pragma("GCC diagnostic ignored \"-Wpedantic\"") +#endif + #include + +#if defined (__GNUC__) +_Pragma("GCC diagnostic pop") +#endif + #endif // RAAL_SOFTDEVICE unsigned int m_seed; diff --git a/src/platform/random/nrf_802154_random_stdlib.c b/src/platform/random/nrf_802154_random_stdlib.c index 65e6dfb..4fcc540 100644 --- a/src/platform/random/nrf_802154_random_stdlib.c +++ b/src/platform/random/nrf_802154_random_stdlib.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2019, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -44,7 +45,20 @@ #include "nrf.h" #if RAAL_SOFTDEVICE + +#if defined (__GNUC__) +_Pragma("GCC diagnostic push") +_Pragma("GCC diagnostic ignored \"-Wreturn-type\"") +_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") +_Pragma("GCC diagnostic ignored \"-Wpedantic\"") +#endif + #include + +#if defined (__GNUC__) +_Pragma("GCC diagnostic pop") +#endif + #endif // RAAL_SOFTDEVICE void nrf_802154_random_init(void) diff --git a/src/platform/random/nrf_802154_random_zephyr.c b/src/platform/random/nrf_802154_random_zephyr.c index 9166514..1471332 100644 --- a/src/platform/random/nrf_802154_random_zephyr.c +++ b/src/platform/random/nrf_802154_random_zephyr.c @@ -73,8 +73,8 @@ static uint64_t next(void) void nrf_802154_random_init(void) { - struct device * dev; - int err; + const struct device * dev; + int err; dev = device_get_binding(DT_CHOSEN_ZEPHYR_ENTROPY_LABEL); __ASSERT_NO_MSG(dev != NULL); diff --git a/src/platform/temperature/nrf_802154_temperature.h b/src/platform/temperature/nrf_802154_temperature.h index 71f611b..90c7bc8 100644 --- a/src/platform/temperature/nrf_802154_temperature.h +++ b/src/platform/temperature/nrf_802154_temperature.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/platform/temperature/nrf_802154_temperature_none.c b/src/platform/temperature/nrf_802154_temperature_none.c index f6590b3..bdbdaf3 100644 --- a/src/platform/temperature/nrf_802154_temperature_none.c +++ b/src/platform/temperature/nrf_802154_temperature_none.c @@ -1,31 +1,32 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA +/* + * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** diff --git a/src/rsch/nrf_802154_rsch.c b/src/rsch/nrf_802154_rsch.c deleted file mode 100644 index 507d8ff..0000000 --- a/src/rsch/nrf_802154_rsch.c +++ /dev/null @@ -1,561 +0,0 @@ -#include "nrf_802154_rsch.h" - -#include -#include -#include - -#include "../nrf_802154_debug.h" -#include "nrf_802154_priority_drop.h" -#include "platform/clock/nrf_802154_clock.h" -#include "platform/coex/nrf_802154_wifi_coex.h" -#include "raal/nrf_raal_api.h" -#include "timer_scheduler/nrf_802154_timer_sched.h" - -/* The following macro defines ramp-up time of preconditions [us]. It depends on HF clock, - * which takes the longest to ramp-up out of all preconditions. - * In case of nRF52811, the value of this macro is the sum of 360us of HFXO startup time, - * 31us of timer granularity margin, 55us of POWER_CLOCK_IRQHandler processing time, 60us of - * RTC_IRQHandler processing time and 9us of margin. - * In case of nRF52840, the value of this macro is the sum of 256us of HFXO debounce time, - * 75us of the worst case power-up time for an Epson crystal, 31us of timer granularity margin, - * 50us of POWER_CLOCK_IRQHandler processing time, 60us of RTC_IRQHandler processing time - * and 8us of margin. - */ -#ifdef NRF52811_XXAA -#define PREC_HFXO_STARTUP_TIME 360 -#define PREC_TIMER_GRANULARITY_MARGIN 31 -#define PREC_POWER_CLOCK_IRQ_HANDLER_PROC_TIME 50 -#define PREC_RTC_IRQ_HANDLER_PROC_TIME 60 -#define PREC_RAMP_UP_MARGIN 9 -#define PREC_RAMP_UP_TIME (PREC_HFXO_STARTUP_TIME + \ - PREC_TIMER_GRANULARITY_MARGIN + \ - PREC_POWER_CLOCK_IRQ_HANDLER_PROC_TIME + \ - PREC_RTC_IRQ_HANDLER_PROC_TIME + \ - PREC_RAMP_UP_MARGIN) -#else -#define PREC_HFXO_DEBOUNCE_TIME 256 -#define PREC_CRYSTAL_WORST_CASE_POWER_UP_TIME 75 -#define PREC_TIMER_GRANULARITY_MARGIN 31 -#define PREC_POWER_CLOCK_IRQ_HANDLER_PROC_TIME 50 -#define PREC_RTC_IRQ_HANDLER_PROC_TIME 60 -#define PREC_RAMP_UP_MARGIN 8 -#define PREC_RAMP_UP_TIME (PREC_HFXO_DEBOUNCE_TIME + \ - PREC_CRYSTAL_WORST_CASE_POWER_UP_TIME + \ - PREC_TIMER_GRANULARITY_MARGIN + \ - PREC_POWER_CLOCK_IRQ_HANDLER_PROC_TIME + \ - PREC_RTC_IRQ_HANDLER_PROC_TIME + \ - PREC_RAMP_UP_MARGIN) -#endif - -static volatile uint8_t m_ntf_mutex; ///< Mutex for notyfying core. -static volatile uint8_t m_ntf_mutex_monitor; ///< Mutex monitor, incremented every failed ntf mutex lock. -static volatile uint8_t m_req_mutex; ///< Mutex for requesting preconditions. -static volatile uint8_t m_req_mutex_monitor; ///< Mutex monitor, incremented every failed req mutex lock. -static volatile rsch_prio_t m_last_notified_prio; ///< Last reported approved priority level. -static volatile rsch_prio_t m_approved_prios[RSCH_PREC_CNT]; ///< Priority levels approved by each precondition. -static rsch_prio_t m_requested_prio; ///< Priority requested from all preconditions. -static rsch_prio_t m_cont_mode_prio; ///< Continuous mode priority level. If continuous mode is not requested equal to @ref RSCH_PRIO_IDLE. - -typedef struct -{ - rsch_prio_t prio; ///< Delayed timeslot priority level. If delayed timeslot is not scheduled equal to @ref RSCH_PRIO_IDLE. - uint32_t t0; ///< Time base of the delayed timeslot trigger time. - uint32_t dt; ///< Time delta of the delayed timeslot trigger time. - nrf_802154_timer_t timer; ///< Timer used to trigger delayed timeslot. -} dly_ts_t; - -static dly_ts_t m_dly_ts[RSCH_DLY_TS_NUM]; - -/** @brief Non-blocking mutex for notifying core. - * - * @param[inout] p_mutex Pointer to the mutex data. - * @param[inout] p_mutex_monitor Pointer to the mutex monitor counter. - * - * @retval true Mutex was acquired. - * @retval false Mutex could not be acquired. - */ -static inline bool mutex_trylock(volatile uint8_t * p_mutex, volatile uint8_t * p_mutex_monitor) -{ - nrf_802154_log_entry(mutex_trylock, 2); - - do - { - uint8_t mutex_value = __LDREXB(p_mutex); - - if (mutex_value) - { - __CLREX(); - - (*p_mutex_monitor)++; - - nrf_802154_log_exit(mutex_trylock, 2); - - return false; - } - } - while (__STREXB(1, p_mutex)); - - __DMB(); - - nrf_802154_log_exit(mutex_trylock, 2); - - return true; -} - -/** @brief Release mutex. */ -static inline void mutex_unlock(volatile uint8_t * p_mutex) -{ - nrf_802154_log_entry(mutex_unlock, 2); - - __DMB(); - *p_mutex = 0; - - nrf_802154_log_exit(mutex_unlock, 2); -} - -/** @brief Check maximal priority level required by any of delayed timeslots at the moment. - * - * To meet delayed timeslot timing requirements there is a time window in which radio - * preconditions should be requested. This function is used to prevent releasing preconditions - * in this time window. - * - * @return Maximal priority level required by delayed timeslots. - */ -static rsch_prio_t max_prio_for_delayed_timeslot_get(void) -{ - nrf_802154_log_entry(max_prio_for_delayed_timeslot_get, 2); - - rsch_prio_t result = RSCH_PRIO_IDLE; - uint32_t now = nrf_802154_timer_sched_time_get(); - - for (uint32_t i = 0; i < RSCH_DLY_TS_NUM; i++) - { - dly_ts_t * p_dly_ts = &m_dly_ts[i]; - uint32_t t0 = p_dly_ts->t0; - uint32_t dt = p_dly_ts->dt - PREC_RAMP_UP_TIME - - nrf_802154_timer_sched_granularity_get(); - - if ((p_dly_ts->prio > result) && !nrf_802154_timer_sched_time_is_in_future(now, t0, dt)) - { - result = p_dly_ts->prio; - } - } - - nrf_802154_log_exit(max_prio_for_delayed_timeslot_get, 2); - - return result; -} - -static rsch_prio_t required_prio_lvl_get(void) -{ - nrf_802154_log_entry(required_prio_lvl_get, 2); - - rsch_prio_t result = max_prio_for_delayed_timeslot_get(); - - if (m_cont_mode_prio > result) - { - result = m_cont_mode_prio; - } - - nrf_802154_log_exit(required_prio_lvl_get, 2); - - return result; -} - -/** @brief Set approved priority level @p prio on given precondition @p prec. - * - * When requested priority level equals to the @ref RSCH_PRIO_IDLE this function will approve only - * the @ref RSCH_PRIO_IDLE priority level and drop other approved levels silently. - * - * @param[in] prec Precondition which state will be changed. - * @param[in] prio Approved priority level for given precondition. - */ -static inline void prec_approved_prio_set(rsch_prec_t prec, rsch_prio_t prio) -{ - nrf_802154_log_entry(prec_approved_prio_set, 2); - - assert(prec <= RSCH_PREC_CNT); - - if ((m_requested_prio == RSCH_PRIO_IDLE) && (prio != RSCH_PRIO_IDLE)) - { - // Ignore approved precondition - it was not requested. - return; - } - - assert((m_approved_prios[prec] != prio) || (prio == RSCH_PRIO_IDLE)); - - m_approved_prios[prec] = prio; - - nrf_802154_log_exit(prec_approved_prio_set, 2); -} - -/** @brief Request all preconditions. - */ -static inline void all_prec_update(void) -{ - nrf_802154_log_entry(all_prec_update, 2); - - rsch_prio_t prev_prio; - rsch_prio_t new_prio; - uint8_t monitor; - - do - { - if (!mutex_trylock(&m_req_mutex, &m_req_mutex_monitor)) - { - return; - } - - monitor = m_req_mutex_monitor; - prev_prio = m_requested_prio; - new_prio = required_prio_lvl_get(); - - if (prev_prio != new_prio) - { - m_requested_prio = new_prio; - - if (new_prio == RSCH_PRIO_IDLE) - { - nrf_802154_priority_drop_hfclk_stop(); - prec_approved_prio_set(RSCH_PREC_HFCLK, RSCH_PRIO_IDLE); - - nrf_raal_continuous_mode_exit(); - prec_approved_prio_set(RSCH_PREC_RAAL, RSCH_PRIO_IDLE); - } - else - { - nrf_802154_priority_drop_hfclk_stop_terminate(); - nrf_802154_clock_hfclk_start(); - nrf_raal_continuous_mode_enter(); - } - - nrf_802154_wifi_coex_prio_request(new_prio); - prec_approved_prio_set(RSCH_PREC_COEX, new_prio); - } - - mutex_unlock(&m_req_mutex); - } - while (monitor != m_req_mutex_monitor); - - nrf_802154_log_exit(all_prec_update, 2); -} - -/** @brief Get currently approved priority level. - * - * @return Maximal priority level approved by all radio preconditions. - */ -static inline rsch_prio_t approved_prio_lvl_get(void) -{ - nrf_802154_log_entry(approved_prio_lvl_get, 2); - - rsch_prio_t result = RSCH_PRIO_MAX; - - for (uint32_t i = 0; i < RSCH_PREC_CNT; i++) - { - if (m_approved_prios[i] < result) - { - result = m_approved_prios[i]; - } - } - - nrf_802154_log_exit(approved_prio_lvl_get, 2); - - return result; -} - -/** @brief Check if all preconditions are requested or met at given priority level or higher. - * - * @param[in] prio Minimal priority level requested from preconditions. - * - * @retval true All preconditions are requested or met at given or higher level. - * @retval false At least one precondition is requested at lower level than required. - */ -static inline bool requested_prio_lvl_is_at_least(rsch_prio_t prio) -{ - nrf_802154_log_entry(requested_prio_lvl_is_at_least, 2); - nrf_802154_log_exit(requested_prio_lvl_is_at_least, 2); - - return m_requested_prio >= prio; -} - -/** @brief Notify core if preconditions are approved or denied if current state differs from last reported. - */ -static inline void notify_core(void) -{ - nrf_802154_log_entry(notify_core, 2); - - rsch_prio_t approved_prio_lvl; - uint8_t temp_mon; - - do - { - if (!mutex_trylock(&m_ntf_mutex, &m_ntf_mutex_monitor)) - { - return; - } - - /* It is possible that preemption is not detected (m_ntf_mutex_monitor is read after - * acquiring mutex). It is not a problem because we will call proper handler function - * requested by preempting context. Avoiding this race would generate one additional - * iteration without any effect. - */ - temp_mon = m_ntf_mutex_monitor; - approved_prio_lvl = approved_prio_lvl_get(); - - if (m_last_notified_prio != approved_prio_lvl) - { - m_last_notified_prio = approved_prio_lvl; - - nrf_802154_rsch_continuous_prio_changed(approved_prio_lvl); - } - - mutex_unlock(&m_ntf_mutex); - } - while (temp_mon != m_ntf_mutex_monitor); - - nrf_802154_log_exit(notify_core, 2); -} - -/** Timer callback used to trigger delayed timeslot. - * - * @param[in] p_context Index of the delayed timeslot operation (TX or RX). - */ -static void delayed_timeslot_start(void * p_context) -{ - rsch_dly_ts_id_t dly_ts_id = (rsch_dly_ts_id_t)(uint32_t)p_context; - dly_ts_t * p_dly_ts = &m_dly_ts[dly_ts_id]; - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMER_DELAYED_START); - - nrf_802154_rsch_delayed_timeslot_started(dly_ts_id); - - p_dly_ts->prio = RSCH_PRIO_IDLE; - - all_prec_update(); - notify_core(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMER_DELAYED_START); -} - -/** Timer callback used to request preconditions for delayed timeslot. - * - * @param[in] p_context Index of the delayed timeslot operation (TX or RX). - */ -static void delayed_timeslot_prec_request(void * p_context) -{ - rsch_dly_ts_id_t dly_ts_id = (rsch_dly_ts_id_t)(uint32_t)p_context; - dly_ts_t * p_dly_ts = &m_dly_ts[dly_ts_id]; - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMER_DELAYED_PREC); - - all_prec_update(); - - p_dly_ts->timer.t0 = p_dly_ts->t0; - p_dly_ts->timer.dt = p_dly_ts->dt; - p_dly_ts->timer.callback = delayed_timeslot_start; - p_dly_ts->timer.p_context = p_context; - - nrf_802154_timer_sched_add(&p_dly_ts->timer, true); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMER_DELAYED_PREC); -} - -/*************************************************************************************************** - * Public API - **************************************************************************************************/ - -void nrf_802154_rsch_init(void) -{ - nrf_raal_init(); - nrf_802154_wifi_coex_init(); - - m_ntf_mutex = 0; - m_req_mutex = 0; - m_last_notified_prio = RSCH_PRIO_IDLE; - m_cont_mode_prio = RSCH_PRIO_IDLE; - m_requested_prio = RSCH_PRIO_IDLE; - - for (uint32_t i = 0; i < RSCH_DLY_TS_NUM; i++) - { - m_dly_ts[i].prio = RSCH_PRIO_IDLE; - } - - for (uint32_t i = 0; i < RSCH_PREC_CNT; i++) - { - m_approved_prios[i] = RSCH_PRIO_IDLE; - } -} - -void nrf_802154_rsch_uninit(void) -{ - for (uint32_t i = 0; i < RSCH_DLY_TS_NUM; i++) - { - nrf_802154_timer_sched_remove(&m_dly_ts[i].timer, NULL); - } - - nrf_802154_wifi_coex_uninit(); - nrf_raal_uninit(); -} - -void nrf_802154_rsch_continuous_mode_priority_set(rsch_prio_t prio) -{ - nrf_802154_log(EVENT_TRACE_ENTER, (prio > RSCH_PRIO_IDLE) ? FUNCTION_RSCH_CONTINUOUS_ENTER : - FUNCTION_RSCH_CONTINUOUS_EXIT); - - m_cont_mode_prio = prio; - __DMB(); - - all_prec_update(); - notify_core(); - - nrf_802154_log(EVENT_TRACE_EXIT, (prio > RSCH_PRIO_IDLE) ? FUNCTION_RSCH_CONTINUOUS_ENTER : - FUNCTION_RSCH_CONTINUOUS_EXIT); -} - -void nrf_802154_rsch_continuous_ended(void) -{ - nrf_raal_continuous_ended(); -} - -bool nrf_802154_rsch_timeslot_request(uint32_t length_us) -{ - return nrf_raal_timeslot_request(length_us); -} - -bool nrf_802154_rsch_delayed_timeslot_request(uint32_t t0, - uint32_t dt, - uint32_t length, - rsch_prio_t prio, - rsch_dly_ts_id_t dly_ts_id) -{ - (void)length; - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_DELAYED_TIMESLOT_REQ); - assert(dly_ts_id < RSCH_DLY_TS_NUM); - - dly_ts_t * p_dly_ts = &m_dly_ts[dly_ts_id]; - uint32_t now = nrf_802154_timer_sched_time_get(); - uint32_t req_dt = dt - PREC_RAMP_UP_TIME; - bool result; - - assert(!nrf_802154_timer_sched_is_running(&p_dly_ts->timer)); - assert(p_dly_ts->prio == RSCH_PRIO_IDLE); - assert(prio != RSCH_PRIO_IDLE); - - if (nrf_802154_timer_sched_time_is_in_future(now, t0, req_dt)) - { - p_dly_ts->prio = prio; - p_dly_ts->t0 = t0; - p_dly_ts->dt = dt; - - p_dly_ts->timer.t0 = t0; - p_dly_ts->timer.dt = req_dt; - p_dly_ts->timer.callback = delayed_timeslot_prec_request; - p_dly_ts->timer.p_context = (void *)dly_ts_id; - - nrf_802154_timer_sched_add(&p_dly_ts->timer, false); - - result = true; - } - else if (requested_prio_lvl_is_at_least(RSCH_PRIO_MAX) && - nrf_802154_timer_sched_time_is_in_future(now, t0, dt)) - { - p_dly_ts->prio = prio; - p_dly_ts->t0 = t0; - p_dly_ts->dt = dt; - - p_dly_ts->timer.t0 = t0; - p_dly_ts->timer.dt = dt; - p_dly_ts->timer.callback = delayed_timeslot_start; - p_dly_ts->timer.p_context = (void *)dly_ts_id; - - nrf_802154_timer_sched_add(&p_dly_ts->timer, true); - - result = true; - } - else - { - result = false; - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_DELAYED_TIMESLOT_REQ); - - return result; -} - -bool nrf_802154_rsch_delayed_timeslot_cancel(rsch_dly_ts_id_t dly_ts_id) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_DELAYED_TIMESLOT_CANCEL); - assert(dly_ts_id < RSCH_DLY_TS_NUM); - - bool result = false; - dly_ts_t * p_dly_ts = &m_dly_ts[dly_ts_id]; - bool was_running; - - nrf_802154_timer_sched_remove(&p_dly_ts->timer, &was_running); - - p_dly_ts->prio = RSCH_PRIO_IDLE; - all_prec_update(); - notify_core(); - - result = was_running; - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_DELAYED_TIMESLOT_CANCEL); - - return result; -} - -bool nrf_802154_rsch_timeslot_is_requested(void) -{ - bool result = false; - - for (uint32_t i = 0; i < RSCH_PREC_CNT; i++) - { - if (m_approved_prios[i] > RSCH_PRIO_IDLE) - { - result = true; - break; - } - } - - return result; -} - -bool nrf_802154_rsch_prec_is_approved(rsch_prec_t prec, rsch_prio_t prio) -{ - assert(prec < RSCH_PREC_CNT); - return m_approved_prios[prec] >= prio; -} - -uint32_t nrf_802154_rsch_timeslot_us_left_get(void) -{ - return nrf_raal_timeslot_us_left_get(); -} - -// External handlers - -void nrf_raal_timeslot_started(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMESLOT_STARTED); - - prec_approved_prio_set(RSCH_PREC_RAAL, RSCH_PRIO_MAX); - notify_core(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMESLOT_STARTED); -} - -void nrf_raal_timeslot_ended(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RSCH_TIMESLOT_ENDED); - - prec_approved_prio_set(RSCH_PREC_RAAL, RSCH_PRIO_IDLE); - notify_core(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMESLOT_ENDED); -} - -void nrf_802154_clock_hfclk_ready(void) -{ - prec_approved_prio_set(RSCH_PREC_HFCLK, RSCH_PRIO_MAX); - notify_core(); -} diff --git a/src/rsch/nrf_802154_rsch_crit_sect.c b/src/rsch/nrf_802154_rsch_crit_sect.c deleted file mode 100644 index da8dcf2..0000000 --- a/src/rsch/nrf_802154_rsch_crit_sect.c +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements critical sections for the RSCH module. - * - */ - -#include "nrf_802154_rsch_crit_sect.h" - -#include -#include -#include - -#include "nrf_802154_critical_section.h" -#include "nrf_802154_rsch.h" - -#include - -#define RSCH_EVT_NONE (rsch_prio_t)UINT8_MAX - -static volatile uint8_t m_rsch_pending_evt; ///< Indicator of pending RSCH event. - -/*************************************************************************************************** - * @section RSCH pending events management - **************************************************************************************************/ - -static void rsch_pending_evt_set(rsch_prio_t prio) -{ - volatile uint8_t rsch_pending_evt; // Dummy variable to prevent compilers from removing ldrex - - do - { - rsch_pending_evt = __LDREXB(&m_rsch_pending_evt); - (void)rsch_pending_evt; - } - while (__STREXB((uint8_t)prio, &m_rsch_pending_evt)); -} - -static rsch_prio_t rsch_pending_evt_clear(void) -{ - uint8_t evt_value; - - do - { - evt_value = __LDREXB(&m_rsch_pending_evt); - } - while (__STREXB(RSCH_EVT_NONE, &m_rsch_pending_evt)); - - return (rsch_prio_t)evt_value; -} - -static bool rsch_pending_evt_is_none(void) -{ - return m_rsch_pending_evt == (uint8_t)RSCH_EVT_NONE; -} - -static void rsch_evt_process(rsch_prio_t evt) -{ - if (evt != RSCH_EVT_NONE) - { - nrf_802154_rsch_crit_sect_prio_changed(evt); - } -} - -/*************************************************************************************************** - * @section Public API - **************************************************************************************************/ - -void nrf_802154_rsch_crit_sect_init(void) -{ - m_rsch_pending_evt = RSCH_EVT_NONE; -} - -void nrf_802154_rsch_crit_sect_prio_request(rsch_prio_t prio) -{ - nrf_802154_rsch_continuous_mode_priority_set(prio); -} - -/*************************************************************************************************** - * @section RSCH callbacks - **************************************************************************************************/ - -void nrf_802154_rsch_continuous_prio_changed(rsch_prio_t prio) -{ - bool crit_sect_success = false; - - crit_sect_success = nrf_802154_critical_section_enter(); - - // If we managed to enter critical section, but there is already a pending event, - // it means that the Critical Section module is about to make one more iteration of the - // critical section exit procedure. To prevent race in continuous mode priorities notification, - // we do not notify directly, but just update the pending event. - if (crit_sect_success && rsch_pending_evt_is_none()) - { - nrf_802154_rsch_crit_sect_prio_changed(prio); - } - else - { - rsch_pending_evt_set(prio); - } - - if (crit_sect_success) - { - nrf_802154_critical_section_exit(); - } -} - -/*************************************************************************************************** - * @section Critical section callbacks - **************************************************************************************************/ - -void nrf_802154_critical_section_rsch_enter(void) -{ - // Intentionally empty -} - -void nrf_802154_critical_section_rsch_exit(void) -{ - rsch_evt_process(rsch_pending_evt_clear()); -} - -bool nrf_802154_critical_section_rsch_event_is_pending(void) -{ - return !rsch_pending_evt_is_none(); -} diff --git a/src/rsch/nrf_802154_rsch_crit_sect.h b/src/rsch/nrf_802154_rsch_crit_sect.h deleted file mode 100644 index ff89025..0000000 --- a/src/rsch/nrf_802154_rsch_crit_sect.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef NRF_802154_RSCH_CRIT_SECT_H__ -#define NRF_802154_RSCH_CRIT_SECT_H__ - -#include - -#include "nrf_802154_rsch.h" - -/** - * @defgroup nrf_802154_rsch_crit_sect RSCH event queue used during critical sections - * @{ - * @ingroup nrf_802154_rsch - * @brief The critical section implementation for the RSCH module. - */ - -/** - * @brief Initializes the RSCH critical section module. - */ -void nrf_802154_rsch_crit_sect_init(void); - -/** - * @brief Requests the priority level from RSCH through the critical section module. - * - * @param[in] prio Requested priority level. - */ -void nrf_802154_rsch_crit_sect_prio_request(rsch_prio_t prio); - -/** - * @brief Notifies the core that the approved RSCH priority has changed. - * - * @note This function is called from the critical section context and does not preempt - * other critical sections. - * - * @param[in] prio Approved priority level. - */ -extern void nrf_802154_rsch_crit_sect_prio_changed(rsch_prio_t prio); - -/** - *@} - **/ - -#endif // NRF_802154_RSCH_CRIT_SECT_H__ diff --git a/src/rsch/raal/nrf_raal_config.h b/src/rsch/raal/nrf_raal_config.h deleted file mode 100644 index 014ca19..0000000 --- a/src/rsch/raal/nrf_raal_config.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef NRF_RAAL_CONFIG_H__ -#define NRF_RAAL_CONFIG_H__ - -#ifdef NRF_802154_PROJECT_CONFIG -#include NRF_802154_PROJECT_CONFIG -#endif - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup nrf_raal_config RAAL configuration - * @{ - * @ingroup nrf_802154 - * @brief Configuration of Radio Arbiter Abstraction Layer. - */ - -/** - * @def NRF_RAAL_MAX_CLEAN_UP_TIME_US - * - * The maximum time in which the radio driver must do any clean-up actions on the RADIO peripheral - * and stop using it. - * - */ -#ifndef NRF_RAAL_MAX_CLEAN_UP_TIME_US -#define NRF_RAAL_MAX_CLEAN_UP_TIME_US 91 -#endif - -/** - *@} - **/ - -#ifdef __cplusplus -} -#endif - -#endif // NRF_RAAL_CONFIG_H__ diff --git a/src/rsch/raal/simulator/nrf_802154_debug.h b/src/rsch/raal/simulator/nrf_802154_debug.h deleted file mode 100644 index ef3959a..0000000 --- a/src/rsch/raal/simulator/nrf_802154_debug.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @brief Module that contains debug helpers for the 802.15.4 radio driver for the nRF SoC devices. - * - */ - -#ifndef NRF_802154_DEBUG_H_ -#define NRF_802154_DEBUG_H_ - -#include - -#include "nrf_802154_debug_core.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define EVENT_TIMESLOT_REQUEST 0x0007UL -#define EVENT_TIMESLOT_REQUEST_RESULT 0x0008UL - -/* Reserved for RAAL: 0x0300 - 0x047F */ - -#define FUNCTION_RAAL_CRIT_SECT_ENTER 0x0301UL -#define FUNCTION_RAAL_CRIT_SECT_EXIT 0x0302UL -#define FUNCTION_RAAL_CONTINUOUS_ENTER 0x0303UL -#define FUNCTION_RAAL_CONTINUOUS_EXIT 0x0304UL - -#define FUNCTION_RAAL_SIG_HANDLER 0x0400UL -#define FUNCTION_RAAL_SIG_EVENT_START 0x0401UL -#define FUNCTION_RAAL_SIG_EVENT_MARGIN 0x0402UL -#define FUNCTION_RAAL_SIG_EVENT_EXTEND 0x0403UL -#define FUNCTION_RAAL_SIG_EVENT_ENDED 0x0404UL -#define FUNCTION_RAAL_SIG_EVENT_RADIO 0x0405UL -#define FUNCTION_RAAL_SIG_EVENT_EXTEND_SUCCESS 0x0406UL -#define FUNCTION_RAAL_SIG_EVENT_EXTEND_FAIL 0x0407UL -#define FUNCTION_RAAL_EVT_BLOCKED 0x0408UL -#define FUNCTION_RAAL_EVT_SESSION_IDLE 0x0409UL -#define FUNCTION_RAAL_EVT_HFCLK_READY 0x040AUL -#define FUNCTION_RAAL_SIG_EVENT_MARGIN_MOVE 0x040BUL - -#ifdef __cplusplus -} -#endif - -#endif /* NRF_802154_DEBUG_H_ */ diff --git a/src/rsch/raal/simulator/nrf_raal_simulator.c b/src/rsch/raal/simulator/nrf_raal_simulator.c deleted file mode 100644 index 7bfae69..0000000 --- a/src/rsch/raal/simulator/nrf_raal_simulator.c +++ /dev/null @@ -1,251 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements the nrf 802.15.4 simulated radio arbiter. - * - * This arbiter should be used for testing driver and tweaking other arbiters. - * - */ - -#include "rsch/raal/nrf_raal_api.h" - -#include -#include -#include - -#include "nrf.h" -#include "nrf_802154_debug.h" - -static bool m_continuous_requested; -static bool m_continuous_granted; - -static uint16_t m_time_interval = 250; // ms -static uint16_t m_ble_duty = 10; // ms -static uint16_t m_pre_preemption_notification = 150; // us - -static uint32_t m_ended_timestamp; -static uint32_t m_started_timestamp; -static uint32_t m_margin_timestamp; - -static void continuous_grant(void) -{ - if (m_continuous_requested && !m_continuous_granted) - { - nrf_802154_pin_set(PIN_DBG_TIMESLOT_ACTIVE); - m_continuous_granted = true; - nrf_raal_timeslot_started(); - } -} - -static void continuous_revoke(void) -{ - if (m_continuous_requested && m_continuous_granted) - { - nrf_802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE); - m_continuous_granted = false; - nrf_raal_timeslot_ended(); - } -} - -static uint32_t time_get(void) -{ - NRF_TIMER0->TASKS_CAPTURE[1] = 1; - return NRF_TIMER0->CC[1]; -} - -void nrf_raal_init(void) -{ - m_ended_timestamp = m_time_interval * 1000UL; - m_started_timestamp = m_ble_duty * 1000UL; - m_margin_timestamp = (m_time_interval * 1000UL) - m_pre_preemption_notification; - - NRF_MWU->PREGION[0].SUBS = 0x00000002; - NRF_MWU->INTENSET = MWU_INTENSET_PREGION0WA_Msk | MWU_INTENSET_PREGION0RA_Msk; - - NVIC_SetPriority(MWU_IRQn, 0); - NVIC_ClearPendingIRQ(MWU_IRQn); - NVIC_EnableIRQ(MWU_IRQn); - - NRF_TIMER0->MODE = TIMER_MODE_MODE_Timer; - NRF_TIMER0->BITMODE = TIMER_BITMODE_BITMODE_24Bit; - NRF_TIMER0->PRESCALER = 4; - NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk; - NRF_TIMER0->CC[0] = m_started_timestamp; - - NVIC_SetPriority(TIMER0_IRQn, 1); - NVIC_ClearPendingIRQ(TIMER0_IRQn); - NVIC_EnableIRQ(TIMER0_IRQn); - - m_continuous_requested = false; - - NRF_TIMER0->TASKS_START = 1; -} - -void nrf_raal_uninit(void) -{ - // Intentionally empty. -} - -void nrf_raal_continuous_mode_enter(void) -{ - uint32_t time; - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_CONTINUOUS_ENTER); - - assert(!m_continuous_requested); - - m_continuous_requested = true; - - NVIC_DisableIRQ(TIMER0_IRQn); - __DSB(); - __ISB(); - - time = time_get(); - - if ((time >= m_started_timestamp) && (time < m_margin_timestamp)) - { - continuous_grant(); - } - - NVIC_EnableIRQ(TIMER0_IRQn); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_ENTER); -} - -void nrf_raal_continuous_mode_exit(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_CONTINUOUS_EXIT); - - assert(m_continuous_requested); - - m_continuous_requested = false; - m_continuous_granted = false; - - nrf_802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_EXIT); -} - -void nrf_raal_continuous_ended(void) -{ - // Intentionally empty. -} - -bool nrf_raal_timeslot_request(uint32_t length_us) -{ - uint32_t timer; - - assert(m_continuous_requested); - - if (!m_continuous_granted) - { - return false; - } - - timer = time_get(); - - return (timer >= m_started_timestamp) && ((timer + length_us) < m_margin_timestamp); -} - -uint32_t nrf_raal_timeslot_us_left_get(void) -{ - uint32_t timer = time_get(); - - return ((timer >= m_started_timestamp) && (timer < m_margin_timestamp)) ? - (m_margin_timestamp - timer) : 0; -} - -void TIMER0_IRQHandler(void) -{ - uint32_t ev_timestamp; - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_HANDLER); - - if (NRF_TIMER0->EVENTS_COMPARE[0]) - { - while (time_get() >= NRF_TIMER0->CC[0]) - { - NRF_TIMER0->EVENTS_COMPARE[0] = 0; - - ev_timestamp = NRF_TIMER0->CC[0]; - - if (ev_timestamp == m_ended_timestamp) - { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_ENDED); - - NRF_MWU->REGIONENSET = MWU_REGIONENSET_PRGN0WA_Msk | MWU_REGIONENSET_PRGN0RA_Msk; - - NRF_TIMER0->TASKS_STOP = 1; - NRF_TIMER0->TASKS_CLEAR = 1; - - NRF_TIMER0->CC[0] = m_started_timestamp; - - NRF_TIMER0->TASKS_START = 1; - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_ENDED); - } - else if (ev_timestamp == m_started_timestamp) - { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_START); - - NRF_MWU->REGIONENCLR = MWU_REGIONENCLR_PRGN0WA_Msk | MWU_REGIONENCLR_PRGN0RA_Msk; - - NRF_TIMER0->CC[0] = m_margin_timestamp; - - continuous_grant(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_START); - } - else if (ev_timestamp == m_margin_timestamp) - { - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_MARGIN); - - NRF_TIMER0->CC[0] = m_ended_timestamp; - - continuous_revoke(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_MARGIN); - } - else - { - assert(false); - } - } - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_HANDLER); -} - -void MWU_IRQHandler(void) -{ - assert(false); -} diff --git a/src/rsch/raal/single_phy/single_phy.c b/src/rsch/raal/single_phy/single_phy.c deleted file mode 100644 index 0175ed2..0000000 --- a/src/rsch/raal/single_phy/single_phy.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements the nrf 802.15.4 radio arbiter for single phy. - * - * This arbiter should be used when 802.15.4 is the only wireless protocol used by the application. - * - */ - -#include "rsch/raal/nrf_raal_api.h" - -#include -#include -#include - -static bool m_continuous; - -void nrf_raal_init(void) -{ - m_continuous = false; -} - -void nrf_raal_uninit(void) -{ - // Intentionally empty. -} - -void nrf_raal_continuous_mode_enter(void) -{ - assert(!m_continuous); - - m_continuous = true; - nrf_raal_timeslot_started(); -} - -void nrf_raal_continuous_mode_exit(void) -{ - assert(m_continuous); - - m_continuous = false; -} - -void nrf_raal_continuous_ended(void) -{ - // Intentionally empty. -} - -bool nrf_raal_timeslot_request(uint32_t length_us) -{ - (void)length_us; - - assert(m_continuous); - - return true; -} - -uint32_t nrf_raal_timeslot_us_left_get(void) -{ - return UINT32_MAX; -} diff --git a/src/rsch/raal/softdevice/nrf_802154_debug.h b/src/rsch/raal/softdevice/nrf_802154_debug.h deleted file mode 100644 index ef3959a..0000000 --- a/src/rsch/raal/softdevice/nrf_802154_debug.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @brief Module that contains debug helpers for the 802.15.4 radio driver for the nRF SoC devices. - * - */ - -#ifndef NRF_802154_DEBUG_H_ -#define NRF_802154_DEBUG_H_ - -#include - -#include "nrf_802154_debug_core.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define EVENT_TIMESLOT_REQUEST 0x0007UL -#define EVENT_TIMESLOT_REQUEST_RESULT 0x0008UL - -/* Reserved for RAAL: 0x0300 - 0x047F */ - -#define FUNCTION_RAAL_CRIT_SECT_ENTER 0x0301UL -#define FUNCTION_RAAL_CRIT_SECT_EXIT 0x0302UL -#define FUNCTION_RAAL_CONTINUOUS_ENTER 0x0303UL -#define FUNCTION_RAAL_CONTINUOUS_EXIT 0x0304UL - -#define FUNCTION_RAAL_SIG_HANDLER 0x0400UL -#define FUNCTION_RAAL_SIG_EVENT_START 0x0401UL -#define FUNCTION_RAAL_SIG_EVENT_MARGIN 0x0402UL -#define FUNCTION_RAAL_SIG_EVENT_EXTEND 0x0403UL -#define FUNCTION_RAAL_SIG_EVENT_ENDED 0x0404UL -#define FUNCTION_RAAL_SIG_EVENT_RADIO 0x0405UL -#define FUNCTION_RAAL_SIG_EVENT_EXTEND_SUCCESS 0x0406UL -#define FUNCTION_RAAL_SIG_EVENT_EXTEND_FAIL 0x0407UL -#define FUNCTION_RAAL_EVT_BLOCKED 0x0408UL -#define FUNCTION_RAAL_EVT_SESSION_IDLE 0x0409UL -#define FUNCTION_RAAL_EVT_HFCLK_READY 0x040AUL -#define FUNCTION_RAAL_SIG_EVENT_MARGIN_MOVE 0x040BUL - -#ifdef __cplusplus -} -#endif - -#endif /* NRF_802154_DEBUG_H_ */ diff --git a/src/rsch/raal/softdevice/nrf_raal_softdevice.c b/src/rsch/raal/softdevice/nrf_raal_softdevice.c deleted file mode 100644 index 4b29897..0000000 --- a/src/rsch/raal/softdevice/nrf_raal_softdevice.c +++ /dev/null @@ -1,830 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements the nrf 802.15.4 radio arbiter for softdevice. - * - * This arbiter should be used when 802.15.4 works concurrently with SoftDevice's radio stack. - * - */ - -#include "nrf_raal_softdevice.h" - -#include -#include -#include - -#include -#include -#include "nrf_802154_debug.h" -#include -#include -#include -#include - -#if defined(__GNUC__) -_Pragma("GCC diagnostic push") -_Pragma("GCC diagnostic ignored \"-Wreturn-type\"") -_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") -_Pragma("GCC diagnostic ignored \"-Wpedantic\"") -#endif - -#include -#include -#include -#include - -#if defined(__GNUC__) -_Pragma("GCC diagnostic pop") -#endif - -/*************************************************************************************************** - * @section Defines and typedefs. - **************************************************************************************************/ - -/* - * @brief Defines the only version of the SoftDevice that supports configuration of BLE advertising - * role scheduling. - * - * The only SoftDevice that supports this option is S140 6.1.1 (6001001). The full version - * number for the SoftDevice binary is a decimal number in the form Mmmmbbb, where: - * - M is major version (one or more digits) - * - mmm is minor version (three digits) - * - bbb is bugfix version (three digits). - */ -#define BLE_ADV_SCHED_CFG_SUPPORT_SD_VERSION (6001001) - -/* - * @brief Defines the minimum version of the SoftDevice that correctly handles timeslot releasing. - * - * The first SoftDevice that supports this option is S140 6.1.0 (6001000). The full version - * number for the SoftDevice binary is a decimal number in the form Mmmmbbb, where: - * - M is major version (one or more digits) - * - mmm is minor version (three digits) - * - bbb is bugfix version (three digits). - */ -#define TIMESLOT_RELEASE_SUPPORT_MIN_SD_VERSION (6001000) - -/**@brief Enable Request and End on timeslot safety interrupt. */ -#define ENABLE_REQUEST_AND_END_ON_TIMESLOT_END 0 - -/**@brief RAAL Timer instance. */ -#define RAAL_TIMER NRF_TIMER0 - -/**@brief RAAL Timer interrupt number. */ -#define RAAL_TIMER_IRQn TIMER0_IRQn - -/**@brief Minimum time prior safe margin reached by RTC when TIMER reports reached margin in microseconds. */ -#define MIN_TIME_PRIOR_MARGIN_IS_REACHED_US 31 - -/**@brief Timer compare channel definitions. */ -#define TIMER_CC_ACTION NRF_TIMER_CC_CHANNEL0 -#define TIMER_CC_ACTION_EVENT NRF_TIMER_EVENT_COMPARE0 -#define TIMER_CC_ACTION_INT NRF_TIMER_INT_COMPARE0_MASK - -#define TIMER_CC_CAPTURE NRF_TIMER_CC_CHANNEL1 -#define TIMER_CC_CAPTURE_TASK NRF_TIMER_TASK_CAPTURE1 - -#define MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_TICKS NRF_802154_US_TO_RTC_TICKS( \ - NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US) - -/**@brief PPM constants. */ -#define PPM_UNIT 1000000UL -#define MAX_HFCLK_PPM 40 - -/**@brief Defines states of timeslot. */ -typedef enum -{ - TIMESLOT_STATE_IDLE = 0, - TIMESLOT_STATE_REQUESTED, - TIMESLOT_STATE_GRANTED -} timeslot_state_t; - -/**@brief Define timer actions. */ -typedef enum -{ - TIMER_ACTION_EXTEND, - TIMER_ACTION_MARGIN, -} timer_action_t; - -/*************************************************************************************************** - * @section Static variables. - **************************************************************************************************/ - -/**@brief Defines if module has been initialized. */ -static bool m_initialized = false; - -/**@brief Request parameters. */ -static nrf_radio_request_t m_request; - -/**@brief Return parameter for SD radio signal handler. */ -static nrf_radio_signal_callback_return_param_t m_ret_param; - -/**@brief Current configuration of the RAAL. */ -static nrf_raal_softdevice_cfg_t m_config; - -/**@brief Defines if RAAL is in continuous mode. */ -static volatile bool m_continuous = false; - -/**@brief Defines if RAAL is currently in a timeslot. */ -static volatile timeslot_state_t m_timeslot_state; - -/**@brief Current action of the timer. */ -static timer_action_t m_timer_action; - -/**@brief Current timeslot length. */ -static uint16_t m_timeslot_length; - -/**@brief Previously granted timeslot length. */ -static uint16_t m_prev_timeslot_length; - -/**@brief Interval between successive timeslot extensions. */ -static uint16_t m_extension_interval; - -/**@brief Number of already performed extentions tries on failed event. */ -static volatile uint16_t m_timeslot_extend_tries; - -/**@brief Defines if timeslot releasing works correctly on given SoftDevice version. */ -static bool m_timeslot_releasing; - -/*************************************************************************************************** - * @section Drift calculations - **************************************************************************************************/ - -static uint32_t time_corrected_for_drift_get(uint32_t time) -{ - uint32_t ppm = m_config.lf_clk_accuracy_ppm + MAX_HFCLK_PPM; - - return time - NRF_802154_DIVIDE_AND_CEIL(time * ppm, PPM_UNIT); -} - -static void calculate_config(void) -{ - m_extension_interval = time_corrected_for_drift_get(m_config.timeslot_length); -} - -/*************************************************************************************************** - * @section Operations on RAAL TIMER. - **************************************************************************************************/ - -/**@brief Set timer on timeslot started. */ -static void timer_start(void) -{ - m_timer_action = TIMER_ACTION_EXTEND; - nrf_timer_task_trigger(RAAL_TIMER, NRF_TIMER_TASK_STOP); - nrf_timer_task_trigger(RAAL_TIMER, NRF_TIMER_TASK_CLEAR); - nrf_timer_bit_width_set(RAAL_TIMER, NRF_TIMER_BIT_WIDTH_32); - nrf_timer_cc_write(RAAL_TIMER, TIMER_CC_ACTION, 0); - - nrf_timer_task_trigger(RAAL_TIMER, NRF_TIMER_TASK_START); - NVIC_EnableIRQ(RAAL_TIMER_IRQn); -} - -/**@brief Reset timer. */ -static void timer_reset(void) -{ - NVIC_DisableIRQ(RAAL_TIMER_IRQn); - __DSB(); - __ISB(); - - nrf_timer_task_trigger(RAAL_TIMER, NRF_TIMER_TASK_STOP); - nrf_timer_event_clear(RAAL_TIMER, TIMER_CC_ACTION_EVENT); -} - -/**@brief Get current time on RAAL Timer. */ -static inline uint32_t timer_time_get(void) -{ - nrf_timer_task_trigger(RAAL_TIMER, TIMER_CC_CAPTURE_TASK); - return nrf_timer_cc_read(RAAL_TIMER, TIMER_CC_CAPTURE); -} - -/**@brief Check if timer is set to margin. - * - * @retval true Timer action CC is set to the margin action. - * @retval false Timer action CC is set to the extend action. - */ -static inline bool timer_is_set_to_margin(void) -{ - return m_timer_action == TIMER_ACTION_MARGIN; -} - -static inline uint32_t ticks_to_timeslot_end_get(void) -{ - uint32_t cc = NRF_RTC0->CC[1]; - uint32_t counter = NRF_RTC0->COUNTER; - - // We add one tick as RTC might be just about to increment COUNTER value. - return (cc - (counter + 1)) & RTC_COUNTER_COUNTER_Msk; -} - -static inline uint32_t safe_time_to_timeslot_end_get(void) -{ - uint32_t margin = m_config.timeslot_safe_margin + NRF_RADIO_START_JITTER_US; - uint32_t timeslot_end = NRF_802154_RTC_TICKS_TO_US(ticks_to_timeslot_end_get()); - - if (timeslot_end > margin) - { - return timeslot_end - margin; - } - else - { - return 0; - } -} - -/**@brief Get timeslot margin. */ -static uint32_t timer_get_cc_margin(void) -{ - uint32_t corrected_time_to_margin = time_corrected_for_drift_get( - safe_time_to_timeslot_end_get()); - - return timer_time_get() + corrected_time_to_margin; -} - -/**@brief Set timer action to the timeslot margin. */ -static inline void timer_to_margin_set(void) -{ - uint32_t margin_cc = timer_get_cc_margin(); - - m_timer_action = TIMER_ACTION_MARGIN; - - nrf_timer_event_clear(RAAL_TIMER, TIMER_CC_ACTION_EVENT); - nrf_timer_cc_write(RAAL_TIMER, TIMER_CC_ACTION, margin_cc); - nrf_timer_int_enable(RAAL_TIMER, TIMER_CC_ACTION_INT); -} - -/**@brief Check if margin is already reached. */ -static inline bool timer_is_margin_reached(void) -{ - return timer_is_set_to_margin() && nrf_timer_event_check(RAAL_TIMER, TIMER_CC_ACTION_EVENT) && - safe_time_to_timeslot_end_get() <= MIN_TIME_PRIOR_MARGIN_IS_REACHED_US; -} - -/**@brief Set timer on extend event. */ -static void timer_on_extend_update(void) -{ - NVIC_ClearPendingIRQ(RAAL_TIMER_IRQn); - - if (timer_is_set_to_margin()) - { - uint32_t margin_cc = nrf_timer_cc_read(RAAL_TIMER, TIMER_CC_ACTION); - - margin_cc += m_timeslot_length; - nrf_timer_cc_write(RAAL_TIMER, TIMER_CC_ACTION, margin_cc); - } - else - { - uint16_t extension_interval = (m_prev_timeslot_length == m_config.timeslot_length) ? - m_extension_interval : - time_corrected_for_drift_get(m_prev_timeslot_length); - - nrf_timer_cc_write(RAAL_TIMER, TIMER_CC_ACTION, - nrf_timer_cc_read(RAAL_TIMER, TIMER_CC_ACTION) + extension_interval); - nrf_timer_int_enable(RAAL_TIMER, TIMER_CC_ACTION_INT); - } -} - -/*************************************************************************************************** - * @section Timeslot related functions. - **************************************************************************************************/ - -/**@brief Initialize timeslot internal variables. */ -static inline void timeslot_data_init(void) -{ - m_timeslot_extend_tries = 0; - m_timeslot_length = m_config.timeslot_length; -} - -/**@brief Indicate if timeslot is in idle state. */ -static inline bool timeslot_is_idle(void) -{ - return (m_timeslot_state == TIMESLOT_STATE_IDLE); -} - -/**@brief Indicate if timeslot has been granted. */ -static inline bool timeslot_is_granted(void) -{ - return (m_timeslot_state == TIMESLOT_STATE_GRANTED); -} - -/**@brief Notify driver that timeslot has been started. */ -static inline void timeslot_started_notify(void) -{ - if (timeslot_is_granted() && m_continuous) - { - nrf_raal_timeslot_started(); - } -} - -/**@brief Notify driver that timeslot has been ended. */ -static inline void timeslot_ended_notify(void) -{ - if (!timeslot_is_granted() && m_continuous) - { - nrf_raal_timeslot_ended(); - } -} - -/**@brief Prepare earliest timeslot request. */ -static void timeslot_request_prepare(void) -{ - memset(&m_request, 0, sizeof(m_request)); - m_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST; - m_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_NO_GUARANTEE; - m_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL; - m_request.params.earliest.length_us = m_timeslot_length; - m_request.params.earliest.timeout_us = m_config.timeslot_timeout; -} - -/**@brief Request earliest timeslot. */ -static void timeslot_request(void) -{ - timeslot_request_prepare(); - - m_timeslot_state = TIMESLOT_STATE_REQUESTED; - - // Request timeslot from SoftDevice. - uint32_t err_code = sd_radio_request(&m_request); - - if (err_code != NRF_SUCCESS) - { - m_timeslot_state = TIMESLOT_STATE_IDLE; - } - - nrf_802154_log(EVENT_TIMESLOT_REQUEST, m_request.params.earliest.length_us); - nrf_802154_log(EVENT_TIMESLOT_REQUEST_RESULT, err_code); -} - -/**@brief Decrease timeslot length. */ -static void timeslot_length_decrease(void) -{ - m_timeslot_extend_tries++; - m_timeslot_length = m_timeslot_length >> 1; -} - -/**@brief Fill timeslot parameters with extend action. */ -static void timeslot_extend(uint32_t timeslot_length) -{ - m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND; - m_ret_param.params.extend.length_us = timeslot_length; - - nrf_802154_pin_set(PIN_DBG_TIMESLOT_EXTEND_REQ); - nrf_802154_log(EVENT_TIMESLOT_REQUEST, m_ret_param.params.extend.length_us); -} - -/**@brief Extend timeslot further. */ -static void timeslot_next_extend(void) -{ - // Check if we can make another extend query. - if (m_timeslot_extend_tries < m_config.timeslot_alloc_iters) - { - // Decrease timeslot length. - timeslot_length_decrease(); - - // Try to extend right after start. - timeslot_extend(m_timeslot_length); - } -} - -/*************************************************************************************************** - * @section RAAL TIMER interrupt handler. - **************************************************************************************************/ - -/**@brief Handle timer interrupts. */ -static void timer_irq_handle(void) -{ - // Margin or extend event triggered. - if (nrf_timer_event_check(RAAL_TIMER, TIMER_CC_ACTION_EVENT)) - { - if (timer_is_set_to_margin()) - { - if (timer_is_margin_reached()) - { - // Safe margin exceeded. - nrf_802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_MARGIN); - - m_timeslot_state = TIMESLOT_STATE_IDLE; - timeslot_ended_notify(); - - // Ignore any other events. - timer_reset(); - - // Return and wait for NRF_EVT_RADIO_SESSION_IDLE event. - m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE; - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_MARGIN); - } - else - { - // Move safety margin a little further to suppress clocks drift - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_MARGIN_MOVE); - timer_to_margin_set(); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_MARGIN_MOVE); - } - } - else - { - // Extension margin exceeded. - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_EXTEND); - - nrf_timer_int_disable(RAAL_TIMER, TIMER_CC_ACTION_INT); - nrf_timer_event_clear(RAAL_TIMER, TIMER_CC_ACTION_EVENT); - - if (m_continuous && - (nrf_timer_cc_read(RAAL_TIMER, TIMER_CC_ACTION) + - m_config.timeslot_length < m_config.timeslot_max_length)) - { - // Try to extend timeslot. - timeslot_extend(m_config.timeslot_length); - } - else - { - // We have reached maximum timeslot length. - timer_to_margin_set(); - - m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE; - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_EXTEND); - } - } - else - { - // Should not happen. - assert(false); - } -} - -/*************************************************************************************************** - * @section SoftDevice signal and SoC handlers. - **************************************************************************************************/ - -/**@brief Signal handler. */ -static nrf_radio_signal_callback_return_param_t * signal_handler(uint8_t signal_type) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_HANDLER); - - // Default response. - m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE; - - if (!m_continuous) - { - nrf_802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_ENDED); - - m_timeslot_state = TIMESLOT_STATE_IDLE; - - m_ret_param.callback_action = m_timeslot_releasing ? NRF_RADIO_SIGNAL_CALLBACK_ACTION_END : - NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE; - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_ENDED); - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_HANDLER); - return &m_ret_param; - } - - switch (signal_type) - { - case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START: /**< This signal indicates the start of the radio timeslot. */ - { - nrf_802154_pin_set(PIN_DBG_TIMESLOT_ACTIVE); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_START); - - assert(m_timeslot_state == TIMESLOT_STATE_REQUESTED); - - // Set up timer first with requested timeslot length. - timer_start(); - - // Re-initialize timeslot data for future extensions. - m_prev_timeslot_length = m_timeslot_length; - timeslot_data_init(); - - // Try to extend right after start. - timeslot_extend(m_timeslot_length); - - // Do not notify started timeslot here. Notify after successful extend to make sure - // enough timeslot length is available before notification. - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_START); - break; - } - - case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0: /**< This signal indicates the TIMER0 interrupt. */ - timer_irq_handle(); - break; - - case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO: /**< This signal indicates the NRF_RADIO interrupt. */ - nrf_802154_pin_set(PIN_DBG_TIMESLOT_RADIO_IRQ); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_RADIO); - - if (timeslot_is_granted()) - { - if (!timer_is_margin_reached()) - { - nrf_802154_radio_irq_handler(); - } - else - { - // Handle margin exceeded event. - timer_irq_handle(); - } - } - else - { - NVIC_DisableIRQ(RADIO_IRQn); - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_RADIO); - nrf_802154_pin_clr(PIN_DBG_TIMESLOT_RADIO_IRQ); - break; - - case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED: /**< This signal indicates extend action failed. */ - nrf_802154_pin_tgl(PIN_DBG_TIMESLOT_FAILED); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_EXTEND_FAIL); - - if (!timer_is_set_to_margin()) - { - timer_to_margin_set(); - } - - timeslot_next_extend(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_EXTEND_FAIL); - break; - - case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED: /**< This signal indicates extend action succeeded. */ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_SIG_EVENT_EXTEND_SUCCESS); - - if ((!timer_is_set_to_margin()) && - (ticks_to_timeslot_end_get() < - MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_TICKS)) - { - timer_to_margin_set(); - - m_ret_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE; - } - else - { - timer_on_extend_update(); - m_prev_timeslot_length = m_timeslot_length; - - // Request further extension only if any of previous one failed. - if (m_timeslot_extend_tries != 0) - { - timeslot_next_extend(); - } - } - - if (!timeslot_is_granted()) - { - m_timeslot_state = TIMESLOT_STATE_GRANTED; - timeslot_started_notify(); - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_EVENT_EXTEND_SUCCESS); - break; - - default: - break; - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_SIG_HANDLER); - - return &m_ret_param; -} - -void nrf_raal_softdevice_soc_evt_handler(uint32_t evt_id) -{ - switch (evt_id) - { - case NRF_EVT_RADIO_BLOCKED: - case NRF_EVT_RADIO_CANCELED: - { - nrf_802154_pin_tgl(PIN_DBG_TIMESLOT_BLOCKED); - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_EVT_BLOCKED); - - assert(!timeslot_is_granted()); - - m_timeslot_state = TIMESLOT_STATE_IDLE; - - if (m_continuous) - { - if (m_timeslot_extend_tries < m_config.timeslot_alloc_iters) - { - timeslot_length_decrease(); - } - - timeslot_request(); - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_EVT_BLOCKED); - - break; - } - - case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN: - assert(false); - break; - - case NRF_EVT_RADIO_SESSION_IDLE: - - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_EVT_SESSION_IDLE); - nrf_802154_pin_tgl(PIN_DBG_TIMESLOT_SESSION_IDLE); - - if (m_continuous && timeslot_is_idle()) - { - timeslot_data_init(); - timeslot_request(); - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_EVT_SESSION_IDLE); - - break; - - case NRF_EVT_RADIO_SESSION_CLOSED: - break; - - default: - break; - } -} - -/*************************************************************************************************** - * @section RAAL API. - **************************************************************************************************/ - -void nrf_raal_softdevice_config(const nrf_raal_softdevice_cfg_t * p_cfg) -{ - assert(m_initialized); - assert(!m_continuous); - assert(p_cfg); - - m_config = *p_cfg; - - calculate_config(); -} - -void nrf_raal_init(void) -{ - assert(!m_initialized); - - m_continuous = false; - m_timeslot_state = TIMESLOT_STATE_IDLE; - - m_config.timeslot_length = NRF_RAAL_TIMESLOT_DEFAULT_LENGTH; - m_config.timeslot_alloc_iters = NRF_RAAL_TIMESLOT_DEFAULT_ALLOC_ITERS; - m_config.timeslot_safe_margin = NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN; - m_config.timeslot_max_length = NRF_RAAL_TIMESLOT_DEFAULT_MAX_LENGTH; - m_config.timeslot_timeout = NRF_RAAL_TIMESLOT_DEFAULT_TIMEOUT; - m_config.lf_clk_accuracy_ppm = NRF_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM; - - calculate_config(); - - uint32_t err_code = sd_radio_session_open(signal_handler); - - assert(err_code == NRF_SUCCESS); - (void)err_code; - -#if (SD_VERSION == BLE_ADV_SCHED_CFG_SUPPORT_SD_VERSION) - // Ensure that correct SoftDevice version is flashed. - if (SD_VERSION_GET(MBR_SIZE) == BLE_ADV_SCHED_CFG_SUPPORT_SD_VERSION) - { - // Use improved Advertiser Role Scheduling configuration. - ble_opt_t opt; - - memset(&opt, 0, sizeof(opt)); - opt.common_opt.adv_sched_cfg.sched_cfg = ADV_SCHED_CFG_IMPROVED; - - err_code = sd_ble_opt_set(BLE_COMMON_OPT_ADV_SCHED_CFG, &opt); - - assert(err_code == NRF_SUCCESS); - (void)err_code; - } -#endif - - // Ensure that correct SoftDevice version is flashed. - if (SD_VERSION_GET(MBR_SIZE) >= TIMESLOT_RELEASE_SUPPORT_MIN_SD_VERSION) - { - m_timeslot_releasing = true; - } - - m_initialized = true; -} - -void nrf_raal_uninit(void) -{ - assert(m_initialized); - - uint32_t err_code = sd_radio_session_close(); - - assert(err_code == NRF_SUCCESS); - (void)err_code; - - m_continuous = false; - m_timeslot_state = TIMESLOT_STATE_IDLE; - - nrf_802154_pin_clr(PIN_DBG_TIMESLOT_ACTIVE); -} - -void nrf_raal_continuous_mode_enter(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_CONTINUOUS_ENTER); - - assert(m_initialized); - assert(!m_continuous); - - m_continuous = true; - - if (timeslot_is_idle()) - { - timeslot_data_init(); - timeslot_request(); - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_ENTER); -} - -void nrf_raal_continuous_mode_exit(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RAAL_CONTINUOUS_EXIT); - - assert(m_initialized); - assert(m_continuous); - - if (timeslot_is_granted()) - { - // Reset timer prior marking exiting continuous mode to prevent timeslot release caused by - // the timer - timer_reset(); - - m_continuous = false; - __DMB(); - - nrf_raal_timeslot_ended(); - - // Emulate signal interrupt to inform SD about end of continuous mode. - NVIC_SetPendingIRQ(RADIO_IRQn); - NVIC_EnableIRQ(RADIO_IRQn); - } - else - { - m_continuous = false; - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RAAL_CONTINUOUS_EXIT); -} - -void nrf_raal_continuous_ended(void) -{ - // Intentionally empty. -} - -bool nrf_raal_timeslot_request(uint32_t length_us) -{ - uint32_t us_left; - - if (!m_continuous || !timeslot_is_granted()) - { - return false; - } - - us_left = nrf_raal_timeslot_us_left_get(); - - assert((us_left >= nrf_802154_rx_duration_get(MAX_PACKET_SIZE, - true)) || timer_is_set_to_margin()); - - return length_us < us_left; -} - -uint32_t nrf_raal_timeslot_us_left_get(void) -{ - return timeslot_is_granted() ? safe_time_to_timeslot_end_get() : 0; -} diff --git a/src/rsch/raal/softdevice/nrf_raal_softdevice.h b/src/rsch/raal/softdevice/nrf_raal_softdevice.h deleted file mode 100644 index 9f735c1..0000000 --- a/src/rsch/raal/softdevice/nrf_raal_softdevice.h +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @brief Module that defines the Radio Arbiter Abstraction Layer interface - * using Timeslot API provided by SoftDevice. - * - */ - -#ifndef NRF_RAAL_SOFTDEVICE_H_ -#define NRF_RAAL_SOFTDEVICE_H_ - -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** @brief RAAL SoftDevice default parameters. */ -#define NRF_RAAL_TIMESLOT_DEFAULT_LENGTH 6400 -#define NRF_RAAL_TIMESLOT_DEFAULT_ALLOC_ITERS 5 -#define NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN nrf_raal_softdevice_safe_margin_calc( \ - NRF_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM) -#define NRF_RAAL_TIMESLOT_DEFAULT_TIMEOUT 2500 -#define NRF_RAAL_TIMESLOT_DEFAULT_MAX_LENGTH 120000000 -#define NRF_RAAL_DEFAULT_LF_CLK_ACCURACY_PPM 500 - -#define NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_LFRC_TICKS 4 -#define NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_CRYSTAL_TICKS 3 -#define NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_US 3 - -#define NRF_RAAL_PPM_THRESHOLD 500 - -#define NRF_RAAL_TIMESLOT_SAFE_MARGIN_TICKS(ppm) ((ppm >= NRF_RAAL_PPM_THRESHOLD) ? \ - NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_LFRC_TICKS \ - : \ - NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_CRYSTAL_TICKS) - -/** - * @brief Function-like macro used to calculate a safe margin from the LF clock accuracy - * in ppm unit. - * - * @param[in] ppm LF clock accuracy in ppm units. - */ -#define nrf_raal_softdevice_safe_margin_calc(ppm) (NRF_802154_RTC_TICKS_TO_US( \ - NRF_RAAL_TIMESLOT_SAFE_MARGIN_TICKS( \ - ppm)) \ - + \ - NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_US) - -/** @brief RAAL Softdevice configuration parameters. */ -typedef struct -{ - /** - * @brief Timeslot length requested by the module, in microseconds. - */ - uint32_t timeslot_length; - - /** - * @brief The longest acceptable delay until the start of the requested timeslot, - * in microseconds. - */ - uint32_t timeslot_timeout; - - /** - * @brief The maximum single timeslot length created by the extension processing, - * in microseconds. - */ - uint32_t timeslot_max_length; - - /** - * @brief The maximum number of iteration of dividing timeslot_length by factor of 2 performed - * by the arbiter. - */ - uint16_t timeslot_alloc_iters; - - /** - * @brief The safe margin before the timeslot is finished and nrf_raal_timeslot_ended - * is to be called, in microseconds. @ref nrf_raal_softdevice_safe_margin_calc can be used - * to calculate the proper value based on the clock accuracy. This value can also be selected - * experimentally. - */ - uint16_t timeslot_safe_margin; - - /** - * @brief The clock accuracy in ppm unit. - */ - uint16_t lf_clk_accuracy_ppm; -} nrf_raal_softdevice_cfg_t; - -/** - * @brief Informs the RAAL client about the SoftDevice SoC events. - * - */ -void nrf_raal_softdevice_soc_evt_handler(uint32_t evt_id); - -/** - * @brief Sets non-default parameters of RAAL. - * - */ -void nrf_raal_softdevice_config(const nrf_raal_softdevice_cfg_t * p_cfg); - -/** - *@} - **/ - -#ifdef __cplusplus -} -#endif - -#endif /* NRF_RAAL_SOFTDEVICE_H_ */ diff --git a/src/timer_scheduler/nrf_802154_timer_sched.c b/src/timer_scheduler/nrf_802154_timer_sched.c deleted file mode 100644 index 8b09aad..0000000 --- a/src/timer_scheduler/nrf_802154_timer_sched.c +++ /dev/null @@ -1,475 +0,0 @@ -/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/** - * @file - * This file implements timer scheduler for the nRF 802.15.4 driver. - * - * This implementation supports scheduling of multiple timer instances and can be used from different contexts. - * - * @note Timer scheduler is secured against preemption and adding/removing different timers from different contexts, - * it shall not be used for adding/removing the same timer instance from two contexts at the same time. - * - */ - -#include "nrf_802154_timer_sched.h" - -#include -#include -#include -#include - -#include -#include "../nrf_802154_debug.h" -#include "platform/lp_timer/nrf_802154_lp_timer.h" - -#if defined(__ICCARM__) -_Pragma("diag_suppress=Pe167") -#endif - -static volatile uint8_t m_timer_mutex; ///< Mutex for starting the timer. -static volatile uint8_t m_fired_mutex; ///< Mutex for the timer firing procedure. -static volatile uint8_t m_queue_changed_cntr; ///< Information that scheduler queue was modified. -static volatile nrf_802154_timer_t * mp_head; ///< Head of the running timers list. - -/** @brief Non-blocking mutex for starting the timer. - * - * @retval true Mutex was acquired. - * @retval false Mutex could not be acquired. - */ -static inline bool mutex_trylock(volatile uint8_t * p_mutex) -{ - do - { - volatile uint8_t mutex_value = __LDREXB(p_mutex); - - if (mutex_value) - { - __CLREX(); - return false; - } - } - while (__STREXB(1, p_mutex)); - - __DMB(); - - return true; -} - -/** @brief Release mutex. */ -static inline void mutex_unlock(volatile uint8_t * p_mutex) -{ - __DMB(); - *p_mutex = 0; -} - -/** @brief Increment queue counter value to detect changes in the queue. */ -static inline void queue_cntr_bump(void) -{ - volatile uint8_t cntr; - - do - { - cntr = __LDREXB(&m_queue_changed_cntr); - } - while (__STREXB(cntr + 1, &m_queue_changed_cntr)); - - __DMB(); -} - -/** - * @brief Check if @p time_1 is before @p time_2. - * - * @param[in] time_1 First time to compare. - * @param[in] time_2 Second time to compare. - * - * @return True if @p time_1 is before @p time_2, false otherwise. - */ -static inline bool is_time_before(uint32_t time_1, uint32_t time_2) -{ - int32_t diff = time_1 - time_2; - - return diff < 0; -} - -/** - * @brief Check if @p p_timer_1 shall strike earlier than @p p_timer_2. - * - * @param[in] p_timer_1 A pointer to first timer to compare. - * @param[in] p_timer_2 A pointer to second timer to compare. - * - * @return True if @p p_timer_1 shall strike earlier than @p p_timer_2, false otherwise. - */ -static inline bool is_timer_prior(const nrf_802154_timer_t * p_timer_1, - const nrf_802154_timer_t * p_timer_2) -{ - return is_time_before(p_timer_1->t0 + p_timer_1->dt, p_timer_2->t0 + p_timer_2->dt); -} - -/** - * @brief Handle operation on timer with mutex protection. - */ -static inline void handle_timer(void) -{ - volatile nrf_802154_timer_t * p_head; - uint8_t queue_cntr; - - do - { - queue_cntr = m_queue_changed_cntr; - p_head = mp_head; - - if (mutex_trylock(&m_timer_mutex)) - { - if (p_head == NULL) - { - nrf_802154_lp_timer_stop(); - } - else - { - uint32_t t0 = p_head->t0; - uint32_t dt = p_head->dt; - - // Set the timer only if current HEAD wasn't removed - otherwise t0 and dt might've been modified - // between reading t0 and dt and not be a valid combination. - if (p_head == mp_head) - { - nrf_802154_lp_timer_start(t0, dt); - } - } - - mutex_unlock(&m_timer_mutex); - } - } - while (queue_cntr != m_queue_changed_cntr); -} - -/** - * @brief Remove a timer from the queue. - * - * The timer to be removed can be running or not running. If the timer is running, it is removed from - * the timer queue and the value pointed by the @c p_was_running parameter is set to true. If the timer is not running, - * the value pointed by @c p_was_running is set to false. - * - * @param[in,out] p_timer Pointer to the timer to remove from the queue. - * @param[out] p_was_running Informs a caller if the timer was running. Pass NULL if irrelevant. - * - * @retval true @sa handle_timer() shall be called by caller of this function. - * @retval false @sa handle_timer() shall not be called by the caller. - */ -static bool timer_remove(nrf_802154_timer_t * p_timer, bool * p_was_running) -{ - assert(p_timer != NULL); - - nrf_802154_timer_t ** pp_item; - nrf_802154_timer_t * volatile p_next; // Volatile pointer to prevent compiler from removing any code related to this variable during optimization (IAR). - nrf_802154_timer_t * p_cur; - uint8_t queue_cntr; - bool timer_start; - bool timer_stop; - - while (true) - { - queue_cntr = m_queue_changed_cntr; - pp_item = (nrf_802154_timer_t **)&mp_head; - p_next = NULL; - p_cur = NULL; - timer_start = false; - timer_stop = false; - - // Find entry to remove - while (true) - { - p_cur = (nrf_802154_timer_t *)__LDREXW((uint32_t *)pp_item); - - if ((p_cur == NULL) || (p_cur == p_timer)) - { - break; - } - - pp_item = &(p_cur->p_next); - } - - if (queue_cntr != m_queue_changed_cntr) - { - // Higher priority modified the queue while iterating, try again. - continue; - } - - if (p_cur == p_timer) - { - // Entry found. - p_next = p_cur->p_next; - - // Restart timer when removing HEAD and other timer instance is pending. - if (p_cur == mp_head) - { - if (p_next != NULL) - { - timer_start = true; - } - else - { - timer_stop = true; - } - } - } - else - { - // Entry not found - __CLREX(); - break; - } - - if (!__STREXW((uint32_t)p_next, (uint32_t *)pp_item)) - { - // Exit, if exclusive access succeeds. - queue_cntr_bump(); - break; - } - } - - bool was_running = false; - - // Write to the pointer next on removal to ensure that node removal is detected by - // lower priority context in case it was going to be used. - if (p_cur != NULL) - { - was_running = true; - uint32_t temp; - - do - { - // This assignment is used to prevent compiler from removing exclusive load during optimization (IAR). - temp = __LDREXW((uint32_t *)&p_cur->p_next); - assert((void *)temp != p_cur); - } - while (__STREXW(temp, (uint32_t *)&p_cur->p_next)); - } - - if (p_was_running != NULL) - { - *p_was_running = was_running; - } - - return (timer_start || timer_stop); -} - -void nrf_802154_timer_sched_init(void) -{ - mp_head = NULL; - m_timer_mutex = 0; - m_fired_mutex = 0; - m_queue_changed_cntr = 0; -} - -void nrf_802154_timer_sched_deinit(void) -{ - nrf_802154_lp_timer_stop(); - - mp_head = NULL; -} - -uint32_t nrf_802154_timer_sched_time_get(void) -{ - return nrf_802154_lp_timer_time_get(); -} - -uint32_t nrf_802154_timer_sched_granularity_get(void) -{ - return nrf_802154_lp_timer_granularity_get(); -} - -bool nrf_802154_timer_sched_time_is_in_future(uint32_t now, uint32_t t0, uint32_t dt) -{ - uint32_t target_time = t0 + dt; - int32_t difference = target_time - now; - - return difference > 0; -} - -uint32_t nrf_802154_timer_sched_remaining_time_get(const nrf_802154_timer_t * p_timer) -{ - assert(p_timer != NULL); - - uint32_t now = nrf_802154_lp_timer_time_get(); - uint32_t expiration = p_timer->t0 + p_timer->dt; - int32_t remaining = expiration - now; - - if (remaining > 0) - { - return (uint32_t)remaining; - } - else - { - return 0ul; - } -} - -void nrf_802154_timer_sched_add(nrf_802154_timer_t * p_timer, bool round_up) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TSCH_ADD); - - assert(p_timer != NULL); - assert(p_timer->callback != NULL); - - if (round_up) - { - p_timer->dt += nrf_802154_lp_timer_granularity_get() - 1; - } - - if (timer_remove(p_timer, NULL)) - { - handle_timer(); - } - - nrf_802154_timer_t ** pp_item; - nrf_802154_timer_t * p_next; - uint8_t queue_cntr; - - while (true) - { - queue_cntr = m_queue_changed_cntr; - pp_item = (nrf_802154_timer_t **)&mp_head; - p_next = NULL; - - // Search the current queue to find appropriate position to insert timer. - while (true) - { - nrf_802154_timer_t * p_cur = (nrf_802154_timer_t *)__LDREXW((uint32_t *)pp_item); - - assert(p_cur != p_timer); - - if (p_cur == NULL) - { - // No HEAD or insert at the end. - p_next = NULL; - break; - } - - if (is_timer_prior(p_timer, p_cur)) - { - // Insert at the beginning with existing HEAD or somewhere in the middle. - p_next = p_cur; - break; - } - - pp_item = &(p_cur->p_next); - } - - if (queue_cntr != m_queue_changed_cntr) - { - // Higher priority modified the queue while iterating, try again. - continue; - } - - assert(p_next != p_timer); - p_timer->p_next = p_next; - - if (!__STREXW((uint32_t)p_timer, (uint32_t *)pp_item)) - { - // Exit, if exclusive access succeeds. - queue_cntr_bump(); - break; - } - } - - if (mp_head == p_timer) - { - handle_timer(); - } - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TSCH_ADD); -} - -void nrf_802154_timer_sched_remove(nrf_802154_timer_t * p_timer, bool * p_was_running) -{ - if (timer_remove(p_timer, p_was_running)) - { - handle_timer(); - } -} - -bool nrf_802154_timer_sched_is_running(nrf_802154_timer_t * p_timer) -{ - uint8_t queue_cntr; - bool result; - - do - { - result = false; - queue_cntr = m_queue_changed_cntr; - - for (volatile nrf_802154_timer_t * p_cur = mp_head; - p_cur != NULL; - p_cur = p_cur->p_next) - { - if (p_cur == p_timer) - { - result = true; - break; - } - } - } - while (queue_cntr != m_queue_changed_cntr); - - return result; -} - -void nrf_802154_lp_timer_fired(void) -{ - nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TSCH_FIRED); - - if (mutex_trylock(&m_fired_mutex)) - { - nrf_802154_timer_t * p_timer = (nrf_802154_timer_t *)mp_head; - - if (p_timer != NULL) - { - nrf_802154_timer_callback_t callback = p_timer->callback; - void * p_context = p_timer->p_context; - - bool was_running; - - (void)timer_remove(p_timer, &was_running); - - if (was_running && (callback != NULL)) - { - callback(p_context); - } - } - - mutex_unlock(&m_fired_mutex); - } - - handle_timer(); - - nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TSCH_FIRED); -}