hal_nordic/drivers/nrf_802154/driver/src/nrf_802154_request_swi.c

913 lines
33 KiB
C

/*
* Copyright (c) 2017 - 2021, Nordic Semiconductor ASA
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* 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 requests to the driver triggered by the MAC layer through SWI.
*
*/
#include "nrf_802154_request.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "nrf_802154_config.h"
#include "nrf_802154_core.h"
#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_types.h"
#include "nrf_802154_utils.h"
#include "hal/nrf_radio.h"
#include "hal/nrf_egu.h"
#include "mac_features/nrf_802154_delayed_trx.h"
#include "platform/nrf_802154_irq.h"
#include <nrf.h>
/** 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,
REQ_TYPE_TRANSMIT_AT,
REQ_TYPE_TRANSMIT_AT_CANCEL,
REQ_TYPE_RECEIVE_AT,
REQ_TYPE_RECEIVE_AT_CANCEL,
} 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.
uint32_t id; ///< Identifier of a reception window.
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.
uint8_t * p_data; ///< Pointer to a buffer containing PHR and PSDU of the frame to transmit.
nrf_802154_transmit_params_t * p_params; ///< Pointer to transmission parameters.
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.
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
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.
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
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
{
req_originator_t req_orig; ///< Request originator.
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.
#if NRF_802154_DELAYED_TRX_ENABLED
struct
{
uint8_t * p_data;
uint32_t t0;
uint32_t dt;
const nrf_802154_transmit_at_metadata_t * p_metadata;
bool * p_result;
} transmit_at;
struct
{
bool * p_result;
} transmit_at_cancel;
struct
{
uint32_t t0;
uint32_t dt;
uint32_t timeout;
uint8_t channel;
uint32_t id;
bool * p_result;
} receive_at;
struct
{
uint32_t id;
bool * p_result;
} receive_at_cancel;
#endif // NRF_802154_DELAYED_TRX_ENABLED
} 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_EGU_IRQN));
}
#define REQUEST_FUNCTION(func_core, func_swi, ...) \
bool result = false; \
\
if (active_vector_priority_is_high()) \
{ \
result = func_core(__VA_ARGS__); \
} \
else \
{ \
assert_interrupt_status(); \
func_swi(__VA_ARGS__, &result); \
} \
\
return result;
#define REQUEST_FUNCTION_NO_ARGS(func_core, func_swi) \
bool result = false; \
\
if (active_vector_priority_is_high()) \
{ \
result = func_core(); \
} \
else \
{ \
assert_interrupt_status(); \
func_swi(&result); \
} \
\
return result;
/** Check if active vector priority is high enough to call requests directly.
*
* @retval true Active vector priority is greater or equal to SWI priority.
* @retval false Active vector priority is lower than SWI priority.
*/
static bool active_vector_priority_is_high(void)
{
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[in] id Identifier of the reception window.
* @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,
uint32_t id,
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.id = id;
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] p_params Pointer to transmission parameters.
* @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,
uint8_t * p_data,
nrf_802154_transmit_params_t * p_params,
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.p_params = p_params;
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();
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @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();
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
/**
* @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(req_originator_t req_orig, 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;
p_slot->data.channel_update.req_orig = req_orig;
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();
}
#if NRF_802154_DELAYED_TRX_ENABLED
static void swi_transmit_at(uint8_t * p_data,
uint32_t t0,
uint32_t dt,
const nrf_802154_transmit_at_metadata_t * p_metadata,
bool * p_result)
{
nrf_802154_req_data_t * p_slot = req_enter();
p_slot->type = REQ_TYPE_TRANSMIT_AT;
p_slot->data.transmit_at.p_data = p_data;
p_slot->data.transmit_at.t0 = t0;
p_slot->data.transmit_at.dt = dt;
p_slot->data.transmit_at.p_metadata = p_metadata;
p_slot->data.transmit_at.p_result = p_result;
req_exit();
}
static void swi_transmit_at_cancel(bool * p_result)
{
nrf_802154_req_data_t * p_slot = req_enter();
p_slot->type = REQ_TYPE_TRANSMIT_AT_CANCEL;
p_slot->data.transmit_at_cancel.p_result = p_result;
req_exit();
}
static void swi_receive_at(uint32_t t0,
uint32_t dt,
uint32_t timeout,
uint8_t channel,
uint32_t id,
bool * p_result)
{
nrf_802154_req_data_t * p_slot = req_enter();
p_slot->type = REQ_TYPE_RECEIVE_AT;
p_slot->data.receive_at.t0 = t0;
p_slot->data.receive_at.dt = dt;
p_slot->data.receive_at.timeout = timeout;
p_slot->data.receive_at.channel = channel;
p_slot->data.receive_at.id = id;
p_slot->data.receive_at.p_result = p_result;
req_exit();
}
static void swi_receive_at_cancel(uint32_t id, bool * p_result)
{
nrf_802154_req_data_t * p_slot = req_enter();
p_slot->type = REQ_TYPE_RECEIVE_AT_CANCEL;
p_slot->data.receive_at_cancel.id = id;
p_slot->data.receive_at_cancel.p_result = p_result;
req_exit();
}
#endif // NRF_802154_DELAYED_TRX_ENABLED
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, swi_sleep, term_lvl)
}
bool nrf_802154_request_receive(nrf_802154_term_t term_lvl,
req_originator_t req_orig,
nrf_802154_notification_func_t notify_function,
bool notify_abort,
uint32_t id)
{
REQUEST_FUNCTION(nrf_802154_core_receive,
swi_receive,
term_lvl,
req_orig,
notify_function,
notify_abort,
id)
}
bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl,
req_originator_t req_orig,
uint8_t * p_data,
nrf_802154_transmit_params_t * p_params,
nrf_802154_notification_func_t notify_function)
{
REQUEST_FUNCTION(nrf_802154_core_transmit,
swi_transmit,
term_lvl,
req_orig,
p_data,
p_params,
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,
swi_energy_detection,
term_lvl,
time_us)
}
bool nrf_802154_request_cca(nrf_802154_term_t term_lvl)
{
REQUEST_FUNCTION(nrf_802154_core_cca, swi_cca, term_lvl)
}
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl)
{
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)
}
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
bool nrf_802154_request_buffer_free(uint8_t * 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(req_originator_t req_orig)
{
REQUEST_FUNCTION(nrf_802154_core_channel_update, swi_channel_update, req_orig)
}
bool nrf_802154_request_cca_cfg_update(void)
{
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, swi_rssi_measure)
}
bool nrf_802154_request_rssi_measurement_get(int8_t * p_rssi)
{
REQUEST_FUNCTION(nrf_802154_core_last_rssi_measurement_get,
swi_rssi_measurement_get,
p_rssi)
}
#if NRF_802154_DELAYED_TRX_ENABLED
bool nrf_802154_request_transmit_raw_at(uint8_t * p_data,
uint32_t t0,
uint32_t dt,
const nrf_802154_transmit_at_metadata_t * p_metadata)
{
REQUEST_FUNCTION(nrf_802154_delayed_trx_transmit, swi_transmit_at, p_data, t0, dt, p_metadata);
}
bool nrf_802154_request_transmit_at_cancel(void)
{
REQUEST_FUNCTION_NO_ARGS(nrf_802154_delayed_trx_transmit_cancel, swi_transmit_at_cancel);
}
bool nrf_802154_request_receive_at(uint32_t t0,
uint32_t dt,
uint32_t timeout,
uint8_t channel,
uint32_t id)
{
REQUEST_FUNCTION(nrf_802154_delayed_trx_receive, swi_receive_at, t0, dt, timeout, channel, id);
}
bool nrf_802154_request_receive_at_cancel(uint32_t id)
{
REQUEST_FUNCTION(nrf_802154_delayed_trx_receive_cancel, swi_receive_at_cancel, id);
}
#endif // NRF_802154_DELAYED_TRX_ENABLED
/**@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,
p_slot->data.receive.id);
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.p_params,
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;
#if NRF_802154_CARRIER_FUNCTIONS_ENABLED
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;
#endif // NRF_802154_CARRIER_FUNCTIONS_ENABLED
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(p_slot->data.channel_update.req_orig);
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;
#if NRF_802154_DELAYED_TRX_ENABLED
case REQ_TYPE_TRANSMIT_AT:
*(p_slot->data.transmit_at.p_result) =
nrf_802154_delayed_trx_transmit(p_slot->data.transmit_at.p_data,
p_slot->data.transmit_at.t0,
p_slot->data.transmit_at.dt,
p_slot->data.transmit_at.p_metadata);
break;
case REQ_TYPE_TRANSMIT_AT_CANCEL:
*(p_slot->data.transmit_at_cancel.p_result) =
nrf_802154_delayed_trx_transmit_cancel();
break;
case REQ_TYPE_RECEIVE_AT:
*(p_slot->data.receive_at.p_result) =
nrf_802154_delayed_trx_receive(p_slot->data.receive_at.t0,
p_slot->data.receive_at.dt,
p_slot->data.receive_at.timeout,
p_slot->data.receive_at.channel,
p_slot->data.receive_at.id);
break;
case REQ_TYPE_RECEIVE_AT_CANCEL:
*(p_slot->data.receive_at_cancel.p_result) =
nrf_802154_delayed_trx_receive_cancel(p_slot->data.receive_at_cancel.id);
break;
#endif // NRF_802154_DELAYED_TRX_ENABLED
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();
}
}