[nrf52xxx] update radio driver to version 1.5.0 (#4122)

This commit is contained in:
Hubert Miś
2019-08-23 10:07:08 -07:00
committed by Jonathan Hui
parent d796b056c5
commit f71d88983e
64 changed files with 1994 additions and 1484 deletions
@@ -29,7 +29,7 @@
*/
/**
* @brief This module defines nRF 802.15.4 FEM abstraction layer.
* @brief This module defines the nRF 802.15.4 Frontend Module abstraction layer.
*
*/
@@ -45,12 +45,12 @@ extern "C" {
/**
* @brief Returns 'power' value.
*
* @note This is just a stub implementation used when MPSL is not linked.
* @note This is a stub implementation used when MPSL is not linked.
*
* @param[in] channel Ignored.
* @param[in] power TX power in dbm.
*
* @retval 'power' value
* @returns Value of 'power' argument.
*/
int8_t nrf_802154_fal_tx_power_get(const uint8_t channel, const int8_t power);
@@ -29,7 +29,7 @@
*/
/**
* @brief Front End Module control for the nRF 802.15.4 radio driver.
* @brief Frontend Module control for the nRF 802.15.4 radio driver.
*
*/
@@ -50,11 +50,21 @@ extern "C" {
* @section Resource configuration.
*/
#ifdef NRF52811_XXAA
/** Default Power Amplifier pin. */
#define NRF_FEM_CONTROL_DEFAULT_PA_PIN 15
#define NRF_FEM_CONTROL_DEFAULT_PA_PIN 19
/** Default Low Noise Amplifier pin. */
#define NRF_FEM_CONTROL_DEFAULT_LNA_PIN 16
#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
@@ -71,39 +81,40 @@ extern "C" {
#if ENABLE_FEM
/**
* @brief Configuration parameters for the PA and LNA.
* @brief Configuration parameters for the Power Amplifier and Low Noise Amplifier.
*/
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 toggle for this amplifier */
uint8_t enable : 1; /**< Enable/disable this amplifier. */
uint8_t active_high : 1; /**< GPIO pin active state for this amplifier. */
uint8_t gpio_pin : 6; /**< GPIO pin to be toggled for this amplifier. */
} nrf_fem_control_pa_lna_cfg_t;
/**
* @brief PA & LNA GPIO toggle configuration
* @brief PA & LNA GPIO toggle configuration.
*
* This option configures the nRF 802.15.4 radio driver to toggle pins when the radio
* is active for use with a power amplifier and/or a low noise amplifier.
* is active for use with a Power Amplifier or a Low Noise Amplifier, or both.
*
* Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided
* by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled.
* Toggling the pins is achieved by using two PPI channels and a GPIOTE channel.
* The hardware channel IDs are provided by the application and must be regarded as reserved
* for as long as any PA/LNA toggling is enabled.
*
* @note Changing this configuration while the radio is in use may have undefined
* @note Changing this configuration while the radio is in use can have undefined
* consequences and must be avoided by the application.
*/
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_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 the Power Amplifier pin toggling. */
uint8_t lna_gpiote_ch_id; /**< GPIOTE channel used for the Low Noise Amplifier pin toggling. */
uint8_t ppi_ch_id_set; /**< PPI channel used for radio Power Amplifier and Low Noise Amplifier pin settings. */
uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing. */
} nrf_fem_control_cfg_t;
/**
* @brief Hardware pins controlled by the Front End Module.
* @brief Hardware pins controlled by the Frontend Module.
*/
typedef enum
{
@@ -112,67 +123,67 @@ typedef enum
NRF_FEM_CONTROL_ANY_PIN,
} nrf_fem_control_pin_t;
/**@brief Set PA & LNA GPIO toggle configuration.
/**@brief Sets the PA & LNA GPIO toggle configuration.
*
* @note This function shall not be called when radio is in use.
* @note Do not call this function when the radio is in use.
*
* @param[in] p_cfg A pointer to the PA & LNA GPIO toggle configuration.
* @param[in] p_cfg Pointer to the PA & LNA GPIO toggle configuration.
*
*/
void nrf_fem_control_cfg_set(const nrf_fem_control_cfg_t * p_cfg);
/**@brief Get PA & LNA GPIO toggle configuration.
/**@brief Gets the PA & LNA GPIO toggle configuration.
*
* @param[out] p_cfg A pointer to the structure for the PA & LNA GPIO toggle configuration.
* @param[out] p_cfg Pointer to the structure for the PA & LNA GPIO toggle configuration.
*
*/
void nrf_fem_control_cfg_get(nrf_fem_control_cfg_t * p_cfg);
/**@brief Activate FEM controller.
/**@brief Activates the Frontend Module controller.
*
* This function should be called when radio wakes up.
* This function is to be called when the radio wakes up.
*/
void nrf_fem_control_activate(void);
/**@brief Deactivate FEM controller.
/**@brief Deactivates the Frontend Module controller.
*
* This function should be called when radio goes to sleep.
* This function is to be called when the radio goes to sleep.
*/
void nrf_fem_control_deactivate(void);
/**@brief Configure PPI to activate one of the Front End Module pins on an appropriate timer event.
/**@brief Configures PPI to activate one of the Frontend Module pins on an appropriate timer event.
*
* @param[in] pin The Front End Module controlled pin to be connected to the PPI.
* @param[in] pin Pin controlled by Frontend Module to be connected to the PPI.
* @param[in] timer_cc_channel Timer CC channel that triggers the @p pin activation through the PPI.
*
*/
void nrf_fem_control_ppi_enable(nrf_fem_control_pin_t pin, nrf_timer_cc_channel_t timer_cc_channel);
/**@brief Clear PPI configuration used to activate one of Front End Module pins.
/**@brief Clears the PPI configuration used to activate one of Frontend Module pins.
*
* @param[in] pin The Front End Module controlled pin to be disconnected from the PPI.
* @param[in] pin Pin controlled by Frontend Module to be disconnected from the PPI.
*
*/
void nrf_fem_control_ppi_disable(nrf_fem_control_pin_t pin);
/**@brief Calculate target time for a timer, which activates one of the Front End Module pins.
/**@brief Calculates the target time for a timer that activates one of the Frontend Module pins.
*
* @param[in] pin The Front End Module controlled pin to be activated.
* @param[in] pin Pin controlled by Frontend Module that is to be activated.
*
* @return @p pin activation delay in microseconds.
* @returns Activation delay of @p pin in microseconds.
*
*/
uint32_t nrf_fem_control_delay_get(nrf_fem_control_pin_t pin);
/**@brief Clear the Power Amplifier and the Low Noise Amplifier pins immediately.
/**@brief Clears the Power Amplifier and the Low Noise Amplifier pins immediately.
*
*/
void nrf_fem_control_pin_clear(void);
/**@brief Configure and set a timer for one of the Front End Module pins activation.
/**@brief Configures and sets a timer for activation of one of the Frontend Module pins.
*
* @param[in] pin The Front End Module controlled pin to be activated.
* @param[in] timer_cc_channel Timer CC channel to set.
* @param[in] pin Pin controlled by Frontend Module to be activated.
* @param[in] timer_cc_channel Timer CC channel to be set.
* @param[in] short_mask Mask of timer shortcuts to be enabled.
*
*/
@@ -180,30 +191,30 @@ void nrf_fem_control_timer_set(nrf_fem_control_pin_t pin,
nrf_timer_cc_channel_t timer_cc_channel,
nrf_timer_short_mask_t short_mask);
/**@brief Clear timer configuration after one of the Front End Module pins deactivation.
/**@brief Clears the timer configuration after the deactivation of one of the Frontend Module pins.
*
* @param[in] pin The Front End Module controlled pin that was deactivated.
* @param[in] short_mask Mask of timer shortcuts to be disabled.
* @param[in] pin Pin controlled by Frontend Module to be deactivated.
* @param[in] short_mask Mask of timer shortcuts to be disabled.
*
*/
void nrf_fem_control_timer_reset(nrf_fem_control_pin_t pin, nrf_timer_short_mask_t short_mask);
/**@brief Setup a PPI fork task necessary for one of the Front End Module pins.
/**@brief Sets up a PPI fork task necessary for one of the Frontend Module pins.
*
* @param[in] pin The Front End Module controlled pin that was deactivated.
* @param[in] ppi_channel PPI channel to connect the fork task to.
* @param[in] pin Pin controlled by Frontend Module that was deactivated.
* @param[in] ppi_channel PPI channel to connect the fork task to.
*
*/
void nrf_fem_control_ppi_fork_setup(nrf_fem_control_pin_t pin,
nrf_ppi_channel_t ppi_channel,
uint32_t task_addr);
/**@brief Setup a PPI task necessary for one of the Front End Module pins.
/**@brief Sets up a PPI task necessary for one of the Frontend Module pins.
*
* @param[in] pin The Front End Module controlled pin that was deactivated.
* @param[in] ppi_channel PPI channel to connect the task to.
* @param[in] event_addr Address of the event to be connected to the PPI.
* @param[in] task_addr Address of the task to be connected to the PPI.
* @param[in] pin Pin controlled by Frontend Module that was deactivated.
* @param[in] ppi_channel PPI channel to connect the task to.
* @param[in] event_addr Address of the event to be connected to the PPI.
* @param[in] task_addr Address of the task to be connected to the PPI.
*
*/
void nrf_fem_control_ppi_task_setup(nrf_fem_control_pin_t pin,
@@ -211,22 +222,22 @@ void nrf_fem_control_ppi_task_setup(nrf_fem_control_pin_t pin,
uint32_t event_addr,
uint32_t task_addr);
/**@brief Clear a PPI fork task configuration for one of the Front End Module pins.
/**@brief Clears a PPI fork task configuration for one of the Frontend Module pins.
*
* @param[in] pin The Front End Module controlled pin that was deactivated.
* @param[in] ppi_channel PPI channel to disconnect the fork task from.
* @param[in] pin Pin controlled by Frontend Module that was deactivated.
* @param[in] ppi_channel PPI channel to disconnect the fork task from.
*
*/
void nrf_fem_control_ppi_fork_clear(nrf_fem_control_pin_t pin, nrf_ppi_channel_t ppi_channel);
/**@brief Setup PPI task and fork that set or clear Front End Module pins on a given event.
/**@brief Sets up a PPI task and a PPI fork that set or clear Frontend Module pins on a given event.
*
* @param[in] ppi_channel PPI channel to connect the task and fork to.
* @param[in] event_addr Address of the event to be connected to the PPI.
* @param[in] lna_pin_set If true, the Low Noise Amplifier pin will be set on the event @p event_addr.
* Otherwise, it will be cleared.
* @param[in] pa_pin_set If true, the Power Amplifier pin will be set on the event @p event_addr.
* Otherwise, it will be cleared.
* @param[in] ppi_channel PPI channel to connect the task and fork to.
* @param[in] event_addr Address of the event to be connected to the PPI.
* @param[in] lna_pin_set If true, the Low Noise Amplifier pin will be set on @p event_addr.
* Otherwise, it will be cleared.
* @param[in] pa_pin_set If true, the Power Amplifier pin will be set on @p event_addr.
* Otherwise, it will be cleared.
*
*/
void nrf_fem_control_ppi_pin_task_setup(nrf_ppi_channel_t ppi_channel,
@@ -39,10 +39,10 @@ extern "C" {
* @section Timings.
*/
/** Time in us when PA GPIO is activated before radio is ready for transmission. */
/** Time in microseconds when PA GPIO is activated before the radio is ready for transmission. */
#define NRF_FEM_PA_TIME_IN_ADVANCE 23
/** Time in us when LNA GPIO is activated before radio is ready for reception. */
/** Time in microseconds when LNA GPIO is activated before the radio is ready for reception. */
#define NRF_FEM_LNA_TIME_IN_ADVANCE 5
#if defined(NRF52840_XXAA) || \
@@ -51,10 +51,10 @@ extern "C" {
defined(NRF52840_AACX) || \
defined(NRF52811_XXAA)
/** Radio ramp-up time in TX mode, in us. */
/** Radio ramp-up time in TX mode, in microseconds. */
#define NRF_FEM_RADIO_TX_STARTUP_LATENCY_US 40
/** Radio ramp-up time in RX mode, in us. */
/** Radio ramp-up time in RX mode, in microseconds. */
#define NRF_FEM_RADIO_RX_STARTUP_LATENCY_US 40
#else
@@ -294,6 +294,7 @@ static bool addr_index_find(const uint8_t * p_addr,
bool extended)
{
uint8_t * p_addr_array;
bool valid_data_type = true;
switch (data_type)
{
@@ -307,10 +308,16 @@ static bool addr_index_find(const uint8_t * p_addr,
break;
default:
valid_data_type = false;
assert(false);
break;
}
if (!valid_data_type)
{
return false;
}
return addr_binary_search(p_addr, p_addr_array, p_location, data_type, extended);
}
@@ -330,6 +337,7 @@ static bool addr_add(const uint8_t * p_addr, uint32_t location, uint8_t data_typ
uint32_t max_addr_array_len;
uint8_t * p_addr_array;
uint8_t entry_size;
bool valid_data_type = true;
switch (data_type)
{
@@ -368,11 +376,12 @@ static bool addr_add(const uint8_t * p_addr, uint32_t location, uint8_t data_typ
break;
default:
valid_data_type = false;
assert(false);
break;
}
if (*p_addr_array_len == max_addr_array_len)
if (!valid_data_type || (*p_addr_array_len == max_addr_array_len))
{
return false;
}
@@ -404,6 +413,7 @@ static bool addr_remove(uint32_t location, uint8_t data_type, bool extended)
uint32_t * p_addr_array_len;
uint8_t * p_addr_array;
uint8_t entry_size;
bool valid_data_type = true;
switch (data_type)
{
@@ -438,11 +448,12 @@ static bool addr_remove(uint32_t location, uint8_t data_type, bool extended)
break;
default:
valid_data_type = false;
assert(false);
break;
}
if (*p_addr_array_len == 0)
if (!valid_data_type || (*p_addr_array_len == 0))
{
return false;
}
@@ -29,9 +29,9 @@
*/
/**
* @brief This module contains an ACK data generator for nRF 802.15.4 radio driver.
* @brief Module that contains an ACK data generator for the nRF 802.15.4 radio driver.
*
* @note Current implementation supports setting pending bit and IEs in 802.15.4-2015 Enh-Ack frames.
* @note The current implementation supports setting pending bit and IEs in 802.15.4-2015 Enh-Ack frames.
*/
#ifndef NRF_802154_ACK_DATA_H
@@ -41,32 +41,32 @@
#include <stdint.h>
/**
* @brief Initialize this module.
* @brief Initializes the ACK data generator module.
*/
void nrf_802154_ack_data_init(void);
/**
* @brief Enable or disable this module.
* @brief Enables or disables the ACK data generator module.
*
* @param[in] enabled True if module should be enabled, false otherwise.
* @param[in] enabled True if the module is to be enabled. False otherwise.
*/
void nrf_802154_ack_data_enable(bool enabled);
/**
* @brief Add address to ACK data list.
* @brief Adds an address to the ACK data list.
*
* ACK frames sent in response to frames with source address matching any address from ACK data list
* will have appropriate data set. If source address does not match any of the addresses in the
* list the ACK frame will not have the data set.
* ACK frames sent in response to frames with the source address matching any address from the ACK data list
* will have the appropriate data set. If the source address does not match any of the addresses in the
* list, the ACK frame will not have the data set.
*
* @param[in] p_addr Pointer to address that should be added to the list.
* @param[in] extended Indication if @p p_addr is extended or short address.
* @param[in] data_type Type of data to set. Please refer to nrf_802154_ack_data_t type.
* @param[in] p_data Pointer to data to set.
* @param[in] data_len Length of @p p_data buffer.
* @param[in] p_addr Pointer to the address that is to be added to the list.
* @param[in] extended Indication if @p p_addr is an extended address or a short address.
* @param[in] data_type Type of data to be set. Refer to the @ref nrf_802154_ack_data_t type.
* @param[in] p_data Pointer to the data to be set.
* @param[in] data_len Length of the @p p_data buffer.
*
* @retval true Address successfully added to the list.
* @retval false Address was not added to the list (list is full).
* @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,
@@ -75,48 +75,48 @@ bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr,
uint8_t data_len);
/**
* @brief Remove address from ACK data list.
* @brief Removes an address from the ACK data list.
*
* ACK frames sent in response to frames with source address matching any address from ACK data list
* will have appropriate data set. If source address does not match any of the addresses in the
* list the ACK frame will not have the data set.
* ACK frames sent in response to frames with the source address matching any address from
* the ACK data list will have the appropriate data set. If the source address does not match
* any of the addresses in the list, the ACK frame will not have the data set.
*
* @param[in] p_addr Pointer to address that should be removed from the list.
* @param[in] extended Indication if @p p_addr is extended or short address.
* @param[in] data_type Type of data that should be cleared for @p p_addr.
* @param[in] p_addr Pointer to the address that is to be removed from the list.
* @param[in] extended Indication if @p p_addr is an extended address or a short address.
* @param[in] data_type Type of data that is to be cleared for @p p_addr.
*
* @retval true Address successfully removed from the list.
* @retval false Address was not removed from the list (address is missing in 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);
/**
* @brief Remove all addresses of given length from ACK data list.
* @brief Removes all addresses of a given length from the ACK data list.
*
* @param[in] extended Indication if all extended or all short addresses should be removed
* from the list.
* @param[in] data_type Type of data that should be cleared for all addresses of given length.
* @param[in] extended Indication if all extended addresses or all short addresses are
* 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);
/**
* @brief Check if pending bit should be set in ACK sent in response to given frame.
* @brief Checks if a pending bit is to be set in the ACK frame sent in response to a given frame.
*
* @param[in] p_frame Pointer to a frame to which ACK frame is being prepared.
* @param[in] p_frame Pointer to the frame for which the ACK frame is being prepared.
*
* @retval true Pending bit should be set.
* @retval false Pending bit should be cleared.
* @retval true Pending bit is to be set.
* @retval false Pending bit is to be cleared.
*/
bool nrf_802154_ack_data_pending_bit_should_be_set(const uint8_t * p_frame);
/**
* @brief Get IE data stored in the list for source address of provided frame.
* @brief Gets the IE data stored in the list for the source address of the provided frame.
*
* @param[in] p_src_addr Pointer to a source address that is searched for in the list.
* @param[in] p_src_addr Pointer to the source address to search for in the list.
* @param[in] src_addr_ext If the source address is extended.
* @param[out] p_ie_length Length of the IE data.
*
* @returns Pointer to stored IE data or NULL if IE data should not be set.
* @returns Either pointer to the stored IE data or NULL if the IE data is not to be set.
*/
const uint8_t * nrf_802154_ack_data_ie_get(const uint8_t * p_src_addr,
bool src_addr_ext,
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contains an acknowledgement generator for 802.15.4 radio driver.
* @brief Module that contains an acknowledgement generator for the 802.15.4 radio driver.
*
*/
@@ -38,15 +38,16 @@
#include <stdint.h>
/** Initialize the ACK generator module. */
/** Initializes the ACK generator module. */
void nrf_802154_ack_generator_init(void);
/** Create an ACK in response to provided frame and insert it into an appropriate radio buffer.
/** Creates an ACK in response to the provided frame and inserts it into a radio buffer.
*
* @param [in] p_frame Pointer to a buffer containing PHR and PSDU of the frame to respond to.
* @param [in] p_frame Pointer to the buffer that contains PHR and PSDU of the frame
* to respond to.
*
* @returns Pointer to a constant buffer containing PHR and PSDU of the created ACK frame,
* or NULL in case of an invalid frame.
* @returns Either pointer to a constant buffer that contains PHR and PSDU
* of the created ACK frame, or NULL in case of an invalid frame.
*/
const uint8_t * nrf_802154_ack_generator_create(const uint8_t * p_frame);
@@ -29,7 +29,8 @@
*/
/**
* @brief This module contains an enhanced acknowledgement (Enh-Ack) generator for 802.15.4 radio driver.
* @brief Module that contains an enhanced acknowledgement (Enh-Ack) generator
* for the 802.15.4 radio driver.
*
*/
@@ -39,14 +40,18 @@
#include <stdbool.h>
#include <stdint.h>
/** Initialize the Enhanced ACK generator module. */
/** Initializes the Enhanced ACK generator module. */
void nrf_802154_enh_ack_generator_init(void);
/** Create an Enhanced ACK in response to provided frame and insert it into an appropriate radio buffer.
/** Creates an Enhanced ACK in response to the provided frame.
*
* @param [in] p_frame Pointer to a buffer containing PHR and PSDU of the frame to respond to.
* This function creates an Enhanced ACK frame and inserts it into a radio buffer.
*
* @returns Pointer to a constant buffer containing PHR and PSDU of the created Enhanced ACK frame.
* @param [in] p_frame Pointer to the buffer that contains PHR and PSDU of the frame
* to respond to.
*
* @returns Pointer to a constant buffer that contains PHR and PSDU
* of the created Enhanced ACK frame.
*/
const uint8_t * nrf_802154_enh_ack_generator_create(const uint8_t * p_frame);
@@ -29,7 +29,8 @@
*/
/**
* @brief This module contains an immediate acknowledgement (Imm-Ack) generator for 802.15.4 radio driver.
* @brief Module that contains an immediate acknowledgement (Imm-Ack) generator
* for the 802.15.4 radio driver.
*
*/
@@ -39,14 +40,18 @@
#include <stdbool.h>
#include <stdint.h>
/** Initialize the Immediate ACK generator module. */
/** Initializes the Immediate ACK generator module. */
void nrf_802154_imm_ack_generator_init(void);
/** Create an Immediate ACK in response to provided frame and insert it into an appropriate radio buffer.
/** Creates an Immediate ACK in response to the provided frame.
*
* @param [in] p_frame Pointer to a buffer containing PHR and PSDU of the frame to respond to.
* This function creates an Immediate ACK frame and inserts it into a radio buffer.
*
* @returns Pointer to a constant buffer containing PHR and PSDU of the created Immediate ACK frame.
* @param [in] p_frame Pointer to the buffer that contains PHR and PSDU of the frame
* to respond to.
*
* @returns Pointer to a constant buffer that contains PHR and PSDU of the created
* Immediate ACK frame.
*/
const uint8_t * nrf_802154_imm_ack_generator_create(const uint8_t * p_frame);
@@ -45,57 +45,57 @@
*/
/**
* @brief Set timeout time for ACK timeout feature.
* @brief Sets the timeout time for the ACK timeout feature.
*
* @param[in] time Timeout time in us.
* Default value is defined in nrf_802154_config.h.
* @param[in] time Timeout time in microseconds.
* The default value is defined in nrf_802154_config.h.
*/
void nrf_802154_ack_timeout_time_set(uint32_t time);
/**
* @brief Abort started ACK timeout procedure.
* @brief Aborts a started ACK timeout procedure.
*
* @param[in] term_lvl Termination level set by request aborting ongoing operation.
* @param[in] req_orig Module that originates this request.
* @param[in] term_lvl Termination level set by the request for aborting the ongoing operation.
* @param[in] req_orig Module that originates the abort request.
*
* If ACK timeout procedure is not running during call, this function does nothing.
* If the ACK timeout procedure is not running during the call, this function does nothing.
*
* @retval true ACK timeout procedure han been stopped.
*/
bool nrf_802154_ack_timeout_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig);
/**
* @brief Handler of transmitted event.
* @brief Handles a transmitted event.
*
* @param[in] p_frame Pointer to the buffer containing transmitted frame.
* @param[in] p_frame Pointer to the buffer that contains the transmitted frame.
*/
void nrf_802154_ack_timeout_transmitted_hook(const uint8_t * p_frame);
/**
* @brief Handler of TX failed event.
* @brief Handles a TX failed event.
*
* @param[in] p_frame Pointer to the buffer containing frame that was not transmitted.
* @param[in] p_frame Pointer to the buffer that contains a frame that was not transmitted.
* @param[in] error Cause of failed transmission.
*
* @retval true TX failed event should be propagated to the MAC layer.
* @retval false TX failed event should not be propagated to the MAC layer. It is handled
* internally.
* @retval true TX failed event is to be propagated to the MAC layer.
* @retval false TX failed event is not to be propagated to the MAC layer. It is handled
* internally in the ACK timeout module.
*/
bool nrf_802154_ack_timeout_tx_failed_hook(const uint8_t * p_frame, nrf_802154_tx_error_t error);
/**
* @brief Handler of TX started event.
* @brief Handles a TX started event.
*
* @param[in] p_frame Pointer to the buffer containing frame being transmitted.
* @param[in] p_frame Pointer to the buffer that contains a frame being transmitted.
*
* @retval true TX started event should be propagated to the MAC layer.
* @retval false TX started event should not be propagated to the MAC layer. It is handled
* internally.
* @retval true TX started event is to be propagated to the MAC layer.
* @retval false TX started event is not to be propagated to the MAC layer. It is handled
* internally in the ACK timeout module.
*/
bool nrf_802154_ack_timeout_tx_started_hook(const uint8_t * p_frame);
/**
* @brief Handler of RX ACK started event.
* @brief Handles a RX ACK started event.
*
*/
void nrf_802154_ack_timeout_rx_ack_started_hook(void);
@@ -206,7 +206,7 @@ bool nrf_802154_csma_ca_abort(nrf_802154_term_t term_lvl, req_originator_t req_o
if (term_lvl >= NRF_802154_TERM_802154)
{
// Stop CSMA-CA if termination level is high enough.
nrf_802154_timer_sched_remove(&m_timer);
nrf_802154_timer_sched_remove(&m_timer, NULL);
procedure_stop();
result = true;
@@ -45,56 +45,60 @@
*/
/**
* @brief Start CSMA-CA procedure for transmission of given frame.
* @brief Starts the CSMA-CA procedure for the transmission of a given frame.
*
* If CSMA-CA procedure is successful and frame is transmitted @sa nrf_802154_tx_started()
* function is called. If CSMA/CA procedure failed and frame cannot be transmitted due to busy
* channel @sa nrf_802154_transmit_failed() function is called.
* If the CSMA-CA procedure is successful and the frame is transmitted,
* the @ref nrf_802154_tx_started() function is called. If the procedure failed and the frame
* cannot be transmitted due to busy channel, the @ref nrf_802154_transmit_failed() function
* is called.
*
* @note CSMA-CA does not timeout waiting for ACK automatically. Waiting for ACK shall be timed out
* by the next layer. ACK timeout timer shall start when @sa nrf_802154_tx_started()
* function is called.
* @note CSMA-CA does not time out automatically when waiting for ACK. Waiting for ACK must be
* timed out by the next layer. The ACK timeout timer must start when
* the @ref nrf_802154_tx_started() function is called.
*
* @param[in] p_data Pointer to a buffer containing PHR and PSDU of the frame that should be transmitted.
* @param[in] p_data Pointer to a buffer the contains PHR and PSDU of the frame
* that is to be transmitted.
*/
void nrf_802154_csma_ca_start(const uint8_t * p_data);
/**
* @brief Abort ongoing CSMA-CA procedure.
* @brief Aborts the ongoing CSMA-CA procedure.
*
* @note This function shall not be called during @sa nrf_802154_csma_ca_start execution
* (i.e. from ISR with higher priority). It would result with unrecoverable runtime error.
* @note Do not call this function during the execution of @ref nrf_802154_csma_ca_start
* (from ISR with higher priority), as it will result in an unrecoverable runtime error.
*
* If CSMA-CA is not running during call, this function does nothing and returns true.
* If CSMA-CA is not running during the call, this function does nothing and returns true.
*
* @param[in] term_lvl Termination level of this request. Selects procedures to abort.
* @param[in] req_orig Module that originates this request.
* @retval true CSMA-CA procedure is not running anymore.
* @retval false CSMA-CA cannot be stopped due to too low termination level.
* @retval false CSMA-CA cannot be stopped because of a too low termination level.
*/
bool nrf_802154_csma_ca_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig);
/**
* @brief Handler of TX failed event.
* @brief Handles a TX failed event.
*
* @param[in] p_frame Pointer to a buffer containing PHR and PSDU of the frame that was not transmitted.
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame
* that was not transmitted.
* @param[in] error Cause of failed transmission.
*
* @retval true TX failed event should be propagated to the MAC layer.
* @retval false TX failed event should not be propagated to the MAC layer. It is handled
* internally.
* @retval true TX failed event is to be propagated to the MAC layer.
* @retval false TX failed event is not to be propagated to the MAC layer. It is handled
* internally in the CSMA-CA module.
*/
bool nrf_802154_csma_ca_tx_failed_hook(const uint8_t * p_frame, nrf_802154_tx_error_t error);
/**
* @brief Handler of TX started event.
* @brief Handles a TX started event.
*
* @param[in] p_frame Pointer to a buffer containing PHR and PSDU of the frame that is being transmitted.
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame
* that is being transmitted.
*
* @retval true TX started event should be propagated to the MAC layer.
* @retval false TX started event should not be propagated to the MAC layer. It is handled
* internally.
* @retval true TX started event is to be propagated to the MAC layer.
* @retval false TX started event is not to be propagated to the MAC layer. It is handled
* internally in the CSMA-CA module.
*/
bool nrf_802154_csma_ca_tx_started_hook(const uint8_t * p_frame);
@@ -43,6 +43,7 @@
#include "../nrf_802154_debug.h"
#include "nrf_802154_config.h"
#include "nrf_802154_const.h"
#include "nrf_802154_frame_parser.h"
#include "nrf_802154_notification.h"
#include "nrf_802154_pib.h"
#include "nrf_802154_procedures_duration.h"
@@ -68,6 +69,16 @@ typedef enum
DELAYED_TRX_OP_STATE_NB ///< Number of delayed operation states.
} delayed_trx_op_state_t;
/**
* @brief RX delayed operation frame data.
*/
typedef struct
{
uint32_t sof_timestamp; ///< Timestamp of last start of frame notification received in RX window.
uint8_t psdu_length; ///< Length in bytes of the frame to be received in RX window.
bool ack_requested; ///< Flag indicating if Ack for the frame to be received in RX window is requested.
} delayed_rx_frame_data_t;
/**
* @brief TX delayed operation configuration.
*/
@@ -87,9 +98,9 @@ static uint8_t m_rx_channel; ///< Channel number on which receptio
static volatile delayed_trx_op_state_t m_dly_op_state[RSCH_DLY_TS_NUM];
/**
* @brief Timestamp of last start of frame notification received in RX window.
* @brief RX delayed operation frame data.
*/
static uint32_t m_sof_timestamp;
static volatile delayed_rx_frame_data_t m_dly_rx_frame;
/**
* Set state of a delayed operation.
@@ -225,15 +236,21 @@ static void notify_rx_timeout(void * p_context)
if (dly_op_state_get(RSCH_DLY_RX) == DELAYED_TRX_OP_STATE_ONGOING)
{
uint32_t now = nrf_802154_timer_sched_time_get();
uint32_t max_frame_length = nrf_802154_rx_duration_get(MAX_PACKET_SIZE, true);
uint32_t sof_timestamp = m_sof_timestamp;
uint32_t now = nrf_802154_timer_sched_time_get();
uint32_t sof_timestamp = m_dly_rx_frame.sof_timestamp;
if (nrf_802154_timer_sched_time_is_in_future(now, sof_timestamp, max_frame_length))
// Make sure that the timestamp has been latched safely. If frame reception preempts the code
// after executing this line, the RX window will not be extended.
__DMB();
uint8_t psdu_length = m_dly_rx_frame.psdu_length;
bool ack_requested = m_dly_rx_frame.ack_requested;
uint32_t frame_length = nrf_802154_rx_duration_get(psdu_length, ack_requested);
if (nrf_802154_timer_sched_time_is_in_future(now, sof_timestamp, frame_length))
{
// @TODO protect against infinite extensions - allow only one timer extension
m_timeout_timer.t0 = sof_timestamp;
m_timeout_timer.dt = max_frame_length;
m_timeout_timer.dt = frame_length;
nrf_802154_timer_sched_add(&m_timeout_timer, true);
}
@@ -265,7 +282,7 @@ static void tx_timeslot_started_callback(bool result)
// To avoid attaching to every possible transmit hook, in order to be able
// to switch from ONGOING to STOPPED state, ONGOING state is not used at all
// and state is changed to STOPPED right after transmit request.
dly_op_state_set(RSCH_DLY_TX, DELAYED_TRX_OP_STATE_PENDING, DELAYED_TRX_OP_STATE_STOPPED);
m_dly_op_state[RSCH_DLY_TX] = DELAYED_TRX_OP_STATE_STOPPED;
if (!result)
{
@@ -288,8 +305,10 @@ static void rx_timeslot_started_callback(bool result)
now = nrf_802154_timer_sched_time_get();
m_timeout_timer.t0 = now;
m_sof_timestamp = now;
m_timeout_timer.t0 = now;
m_dly_rx_frame.sof_timestamp = now;
m_dly_rx_frame.psdu_length = 0;
m_dly_rx_frame.ack_requested = false;
nrf_802154_timer_sched_add(&m_timeout_timer, true);
}
@@ -409,7 +428,7 @@ bool nrf_802154_delayed_trx_receive(uint32_t t0,
m_rx_channel = channel;
// remove timer in case it was left after abort operation
nrf_802154_timer_sched_remove(&m_timeout_timer);
nrf_802154_timer_sched_remove(&m_timeout_timer, NULL);
result = dly_op_request(t0, dt, timeslot_length, RSCH_DLY_RX);
}
@@ -417,11 +436,8 @@ bool nrf_802154_delayed_trx_receive(uint32_t t0,
return result;
}
void nrf_802154_rsch_delayed_timeslot_started(rsch_dly_ts_id_t dly_ts_id)
static inline void timeslot_started_callout(rsch_dly_ts_id_t dly_ts_id)
{
assert(dly_ts_id < RSCH_DLY_TS_NUM);
assert(dly_op_state_get(dly_ts_id) == DELAYED_TRX_OP_STATE_PENDING);
switch (dly_ts_id)
{
case RSCH_DLY_TX:
@@ -433,10 +449,55 @@ void nrf_802154_rsch_delayed_timeslot_started(rsch_dly_ts_id_t dly_ts_id)
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;
result = nrf_802154_rsch_delayed_timeslot_cancel(RSCH_DLY_TX);
m_dly_op_state[RSCH_DLY_TX] = DELAYED_TRX_OP_STATE_STOPPED;
return result;
}
bool nrf_802154_delayed_trx_receive_cancel(void)
{
bool result;
result = nrf_802154_rsch_delayed_timeslot_cancel(RSCH_DLY_RX);
bool was_running;
nrf_802154_timer_sched_remove(&m_timeout_timer, &was_running);
m_dly_op_state[RSCH_DLY_RX] = DELAYED_TRX_OP_STATE_STOPPED;
result = result || was_running;
return result;
}
bool nrf_802154_delayed_trx_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig)
{
bool result = true;
@@ -467,10 +528,12 @@ bool nrf_802154_delayed_trx_abort(nrf_802154_term_t term_lvl, req_originator_t r
return result;
}
void nrf_802154_delayed_trx_rx_started_hook(void)
void nrf_802154_delayed_trx_rx_started_hook(const uint8_t * p_frame)
{
if (dly_op_state_get(RSCH_DLY_RX) == DELAYED_TRX_OP_STATE_ONGOING)
{
m_sof_timestamp = nrf_802154_timer_sched_time_get();
m_dly_rx_frame.sof_timestamp = nrf_802154_timer_sched_time_get();
m_dly_rx_frame.psdu_length = p_frame[PHR_OFFSET];
m_dly_rx_frame.ack_requested = nrf_802154_frame_parser_ar_bit_is_set(p_frame);
}
}
@@ -38,31 +38,31 @@
#include "nrf_802154_types.h"
/**
* @defgroup nrf_802154_delayed_trx Delayed transmission and reception window features.
* @defgroup nrf_802154_delayed_trx Delayed transmission and reception window features
* @{
* @ingroup nrf_802154
* @brief Delayed transmission or receive window.
*
* This module implements delayed transmission and receive window features used in CSL and TSCH
* This module implements delayed transmission and receive window features used in the CSL and TSCH
* modes.
*/
/**
* @brief Request transmission of a frame at given time.
* @brief Requests transmission of a frame at a given time.
*
* If requested transmission is successful and the frame is transmitted the
* @ref nrf_802154_tx_started is called. If the requested frame cannot be transmitted at given time
* the @ref nrf_802154_transmit_failed function is called.
* If the requested transmission is successful and the frame is transmitted, the
* @ref nrf_802154_tx_started function is called. If the requested frame cannot be transmitted
* at the given time, the @ref nrf_802154_transmit_failed function is called.
*
* @note Delayed transmission does not timeout waiting for ACK automatically. Waiting for ACK shall
* be timed out by the next higher layer or the ACK timeout module. The ACK timeout timer
* shall start when the @ref nrf_802154_tx_started function is called.
* @note The delayed transmission does not time out automatically when waiting for ACK.
* Waiting for ACK must be timed out by the next higher layer or the ACK timeout module.
* The ACK timeout timer must start when the @ref nrf_802154_tx_started function is called.
*
* @param[in] p_data Pointer to a buffer containing PHR and PSDU of the frame to be transmitted.
* @param[in] cca If the driver should perform CCA procedure before transmission.
* @param[in] t0 Base of delay time [us].
* @param[in] dt Delta of delay time from @p t0 [us].
* @param[in] channel Number of channel on which the frame should be transmitted.
* @param[in] cca If the driver is to perform the CCA procedure before the transmission.
* @param[in] t0 Base of delay time in microseconds.
* @param[in] dt Delta of the delay time from @p t0 in microseconds.
* @param[in] channel Number of the channel on which the frame is to be transmitted.
*/
bool nrf_802154_delayed_trx_transmit(const uint8_t * p_data,
bool cca,
@@ -70,21 +70,32 @@ bool nrf_802154_delayed_trx_transmit(const uint8_t * p_data,
uint32_t dt,
uint8_t channel);
/**
* @brief Cancels a transmission scheduled by a call to @ref nrf_802154_delayed_trx_transmit.
*
* This function does not cancel transmission if the transmission is already ongoing.
*
* @retval true Successfully cancelled a scheduled transmission.
* @retval false No delayed transmission was scheduled.
*/
bool nrf_802154_delayed_trx_transmit_cancel(void);
/**
*@}
**/
/**
* @brief Request reception of a frame at given time.
* @brief Requests the reception of a frame at a given time.
*
* If the requested is accepted and a frame is received during defined time slot
* @ref nrf_802154_received is called. If the request is rejected due to denied timeslot request
* or reception timeout expired the @ref nrf_802154_receive_failed function is called.
* If the request is accepted and a frame is received during the defined time slot,
* the @ref nrf_802154_received function is called. If the request is rejected due
* to a denied timeslot request or the reception timeout expires,
* the @ref nrf_802154_receive_failed function is called.
*
* @param[in] t0 Base of delay time [us].
* @param[in] dt Delta of delay time from @p t0 [us].
* @param[in] timeout Reception timeout (counted from @p t0 + @p dt) [us].
* @param[in] channel Number of channel on which the frame should be received.
* @param[in] t0 Base of delay time in microseconds.
* @param[in] dt Delta of delay time from @p t0 in microseconds.
* @param[in] timeout Reception timeout (counted from @p t0 + @p dt) in microseconds.
* @param[in] channel Number of the channel on which the frame is to be received.
*/
bool nrf_802154_delayed_trx_receive(uint32_t t0,
uint32_t dt,
@@ -92,24 +103,42 @@ bool nrf_802154_delayed_trx_receive(uint32_t t0,
uint8_t channel);
/**
* @brief Aborts ONGOING delayed receive procedure.
* @brief Cancels a reception scheduled by a call to @ref nrf_802154_delayed_trx_receive.
*
* @param[in] term_lvl Termination level set by request aborting ongoing operation.
* After a call to this function, no reception timeout event will be notified.
*
* @retval true Successfully cancelled a scheduled transmission.
* @retval false No delayed reception was scheduled.
*/
bool nrf_802154_delayed_trx_receive_cancel(void);
/**
* @brief Aborts an ongoing delayed reception procedure.
*
* @param[in] term_lvl Termination level set by the request to abort the ongoing operation.
* @param[in] req_orig Module that originates this request.
*
* If delayed transmit/receive procedure are not running during call, this function does nothing.
* If the delayed transmission/reception procedures are not running during the call,
* this function does nothing.
*
* @retval true Transmission/reception procedures have been stopped.
* @retval false Transmission/reception procedures were not running.
*
* @retval true transmit/receive procedures have been stopped.
*/
bool nrf_802154_delayed_trx_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig);
/**
* @brief Extends timeout timer when reception start is detected and there is not enough time
* left for delayed RX operation.
* @brief Extends the timeout timer when the reception start is detected and there is not enough
* time left for a delayed RX operation.
*
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame
* that is being received.
*
* If the delayed transmission/reception procedures are not running during call,
* this function does nothing.
*
* If delayed transmit/receive procedure are not running during call, this function does nothing.
*/
void nrf_802154_delayed_trx_rx_started_hook(void);
void nrf_802154_delayed_trx_rx_started_hook(const uint8_t * p_frame);
/**
*@}
@@ -29,7 +29,7 @@
*/
/**
* @brief This file implements incoming frame filter API.
* @brief Module that implements the incoming frame filter API.
*
*/
@@ -42,34 +42,35 @@
#include "nrf_802154_types.h"
/**
* @defgroup nrf_802154_filter Incoming frame filter API.
* @defgroup nrf_802154_filter Incoming frame filter API
* @{
* @ingroup nrf_802154
* @brief Procedures used to discard incoming frames that contain unexpected data in PHR or MHR.
* @brief Procedures used to discard the incoming frames that contain unexpected data in PHR or MHR.
*/
/**
* @brief Verify if given part of the frame is valid.
* @brief Verifies if the given part of the frame is valid.
*
* This function is called a few times for each received frame. First call is after FCF is received
* (PSDU length is 1 - @p p_num_bytes value is 1). Subsequent calls are performed when number of
* bytes requested by previous call is available. Iteration ends when function does not request
* any more bytes to check.
* If verified part of the function is correct this function returns true and sets @p p_num_bytes to
* number of bytes that should be available in PSDU during next iteration. If frame is correct and
* there is nothing more to check, function returns true and does not modify @p p_num_bytes value.
* If verified frame is incorrect this function returns false and @p p_num_bytes value is undefined.
* This function is called a few times for each received frame. The first call is after the FCF
* is received (PSDU length is 2 and @p p_num_bytes value is 3). The subsequent calls are performed
* when the number of bytes requested by the previous call is available. The iteration ends
* when the function does not request any more bytes to check.
* If the verified part of the function is correct, this function returns true and sets
* @p p_num_bytes to the number of bytes that should be available in PSDU during the next iteration.
* If the frame is correct and there is nothing more to check, this function returns true
* and does not modify the @p p_num_bytes value. If the verified frame is incorrect, this function
* returns false and the @p p_num_bytes value is undefined.
*
* @param[in] p_data Pointer to a buffer containing PHR and PSDU of incoming frame.
* @param[inout] p_num_bytes Number of bytes available in @p p_data buffer. This value is set to
* requested number of bytes for next iteration or this value is
* unchanged if no more iterations shall be performed during filtering of
* given frame.
* @param[in] p_data Pointer to a buffer that contains PHR and PSDU of the incoming frame.
* @param[inout] p_num_bytes Number of bytes available in @p p_data buffer. This value is either
* set to the requested number of bytes for the next iteration or remains
* unchanged if no more iterations are to be performed during
* the filtering of the given frame.
*
* @retval NRF_802154_RX_ERROR_NONE Verified part of the incoming frame is valid.
* @retval NRF_802154_RX_ERROR_INVALID_FRAME Verified part of the incoming frame is invalid.
* @retval NRF_802154_RX_ERROR_INVALID_DEST_ADDR Incoming frame has destination address that
* mismatches address of this node.
* mismatches the address of this node.
*/
nrf_802154_rx_error_t nrf_802154_filter_frame_part(const uint8_t * p_data, uint8_t * p_num_bytes);
@@ -332,6 +332,11 @@ bool nrf_802154_frame_parser_ie_present_bit_is_set(const uint8_t * p_frame)
return (p_frame[IE_PRESENT_OFFSET] & IE_PRESENT_BIT) ? true : false;
}
bool nrf_802154_frame_parser_ar_bit_is_set(const uint8_t * p_frame)
{
return (p_frame[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT) ? true : false;
}
/***************************************************************************************************
* @section Offset functions
**************************************************************************************************/
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contatins frame parsing utilities for 802.15.4 radio driver.
* @brief Module that contains frame parsing utilities for the 802.15.4 radio driver.
*
*/
@@ -42,243 +42,275 @@
#define NRF_802154_FRAME_PARSER_INVALID_OFFSET 0xff
/**
* @biref Structure containing pointers to parts of MHR and details of MHR structure.
* @biref Structure that contains pointers to parts of MHR and details of MHR structure.
*/
typedef struct
{
const uint8_t * p_dst_panid; ///< Pointer to the destination PAN ID field or NULL if missing.
const uint8_t * p_dst_addr; ///< Pointer to the destination address field or NULL if missing.
const uint8_t * p_src_panid; ///< Pointer to the source PAN ID field or NULL if missing.
const uint8_t * p_src_addr; ///< Pointer to the source address field or NULL if missing.
const uint8_t * p_sec_ctrl; ///< Pointer to the security control field or NULL if missing.
uint8_t dst_addr_size; ///< Size of destination address field.
uint8_t src_addr_size; ///< Size of source address field.
const uint8_t * p_dst_panid; ///< Pointer to the destination PAN ID field, or NULL if missing.
const uint8_t * p_dst_addr; ///< Pointer to the destination address field, or NULL if missing.
const uint8_t * p_src_panid; ///< Pointer to the source PAN ID field, or NULL if missing.
const uint8_t * p_src_addr; ///< Pointer to the source address field, or NULL if missing.
const uint8_t * p_sec_ctrl; ///< Pointer to the security control field, or NULL if missing.
uint8_t dst_addr_size; ///< Size of the destination address field.
uint8_t src_addr_size; ///< Size of the source address field.
uint8_t addressing_end_offset; ///< Offset of the first byte following addressing fields.
} nrf_802154_frame_parser_mhr_data_t;
/**
* @brief Determine if destination address is extended.
* @brief Determines if the destination address is extended.
*
* @param[in] p_frame Pointer to a frame to check.
* @param[in] p_frame Pointer to a frame to be checked.
*
* @retval true If destination address is extended.
* @retval false Otherwise.
* @retval true Destination address is extended.
* @retval false Destination address is not extended.
*/
bool nrf_802154_frame_parser_dst_addr_is_extended(const uint8_t * p_frame);
/**
* @brief Get destination address from provided frame.
* @brief Gets the destination address from the provided frame.
*
* @param[in] p_frame Pointer to a frame.
* @param[out] p_dst_addr_extended Pointer to a value which is true if destination address is extended.
* Otherwise it is false.
* @param[out] p_dst_addr_extended Pointer to a value, which is true if the destination address
* is extended. Otherwise, it is false.
*
* @returns Pointer to the first byte of destination address in @p p_frame.
* NULL if destination address cannot be retrieved.
* @returns Pointer to the first byte of the destination address in @p p_frame.
* NULL if the destination address cannot be retrieved.
*/
const uint8_t * nrf_802154_frame_parser_dst_addr_get(const uint8_t * p_frame,
bool * p_dst_addr_extended);
/**
* @brief Get offset of destination address field in provided frame.
* @brief Gets the offset of the destination address field in the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of destination address field including one byte of frame length.
* Zero if destination address cannot be retrieved.
* @returns Offset in bytes of the destination address field, including one byte
* of the frame length.
* @returns Zero if the destination address cannot be retrieved.
*
*/
uint8_t nrf_802154_frame_parser_dst_addr_offset_get(const uint8_t * p_frame);
/**
* @brief Get destination PAN ID from provided frame.
* @brief Gets the destination PAN ID from the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of destination PAN ID in @p p_frame.
* NULL if destination PAN ID cannot be retrieved.
* @returns Pointer to the first byte of the destination PAN ID in @p p_frame.
* @returns NULL if the destination PAN ID cannot be retrieved.
*
*/
const uint8_t * nrf_802154_frame_parser_dst_panid_get(const uint8_t * p_frame);
/**
* @brief Get offset of destination PAN ID field in provided frame.
* @brief Gets the offset of the destination PAN ID field in the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of destination PAN ID field including one byte of frame length.
* Zero in case the destination PAN ID cannot be retrieved.
* @returns Offset in bytes of the destination PAN ID field, including one byte
* of the frame length.
* @returns Zero in case the destination PAN ID cannot be retrieved.
*
*/
uint8_t nrf_802154_frame_parser_dst_panid_offset_get(const uint8_t * p_frame);
/**
* @brief Get offset of the end of destination address fields.
* @brief Gets the offset of the end of the destination address fields.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset of the first byte following destination addressing fields in the MHR.
* @returns Offset of the first byte following the destination addressing fields in the MHR.
*/
uint8_t nrf_802154_frame_parser_dst_addr_end_offset_get(const uint8_t * p_frame);
/**
* @brief Determine if source address is extended.
* @brief Determines if the source address is extended.
*
* @param[in] p_frame Pointer to a frame to check.
*
* @retval true If source address is extended.
* @retval false Otherwise.
* @retval true The source address is extended.
* @retval false The source address is not extended.
*
*/
bool nrf_802154_frame_parser_src_addr_is_extended(const uint8_t * p_frame);
/**
* @brief Determine if source address is short.
* @brief Determines if the source address is short.
*
* @param[in] p_frame Pointer to a frame to check.
*
* @retval true If source address is short..
* @retval false Otherwise.
* @retval true The source address is short.
* @retval false The source address is not short.
*
*/
bool nrf_802154_frame_parser_src_addr_is_short(const uint8_t * p_frame);
/**
* @brief Get source address from provided frame.
* @brief Gets the source address from the provided frame.
*
* @param[in] p_frame Pointer to a frame.
* @param[out] p_src_addr_extended Pointer to a value which is true if source address is extended.
* Otherwise it is false.
* @param[out] p_src_addr_extended Pointer to a value, which is true if source address is extended.
* Otherwise, it is false.
*
* @returns Pointer to the first byte of the source address in @p p_frame.
* @returns NULL if the source address cannot be retrieved.
*
* @returns Pointer to the first byte of source address in @p p_frame.
* NULL if source address cannot be retrieved.
*/
const uint8_t * nrf_802154_frame_parser_src_addr_get(const uint8_t * p_frame,
bool * p_src_addr_extended);
/**
* @brief Get offset of source address field in provided frame.
* @brief Gets the offset of the source address field in the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of source address field including one byte of frame length.
* Zero if source address cannot be retrieved.
* @returns Offset in bytes of the source address field, including one byte of the frame length.
* @returns Zero if the source address cannot be retrieved.
*
*/
uint8_t nrf_802154_frame_parser_src_addr_offset_get(const uint8_t * p_frame);
/**
* @brief Get source PAN ID from provided frame.
* @brief Gets the source PAN ID from the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of source PAN ID in @p p_frame.
* NULL if source PAN ID cannot be retrieved or if it is compressed.
* @returns Pointer to the first byte of the source PAN ID in @p p_frame.
* @returns NULL if the source PAN ID cannot be retrieved or if it is compressed.
*
*/
const uint8_t * nrf_802154_frame_parser_src_panid_get(const uint8_t * p_frame);
/**
* @brief Get offset of source PAN ID field in provided frame.
* @brief Gets the offset of the source PAN ID field in the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of source PAN ID field including one byte of frame length.
* Zero in case the source PAN ID cannot be retrieved or it is compressed.
* @returns Offset in bytes of the source PAN ID field, including one byte of the frame length.
* @returns Zero if the source PAN ID cannot be retrieved or is compressed.
*
*/
uint8_t nrf_802154_frame_parser_src_panid_offset_get(const uint8_t * p_frame);
/**
* @brief Get pointer and details of MHR parts of given frame
* @brief Gets the pointer and the details of MHR parts of a given frame.
*
* @param[in] p_frame Pointer to a frame to parse.
* @param[out] p_fields Pointer to a structure containing pointers and details of the parsed frame.
* @param[out] p_fields Pointer to a structure that contains pointers and details
* of the parsed frame.
*
* @retval true Frame parsed correctly.
* @retval false Parse error. @p p_fields values are invalid.
*
*/
bool nrf_802154_frame_parser_mhr_parse(const uint8_t * p_frame,
nrf_802154_frame_parser_mhr_data_t * p_fields);
/**
* @brief Get security control field in provided frame.
* @brief Gets the security control field in the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of security control field in @p p_frame.
* NULL if security control cannot be retrieved (security not enabled).
* @returns Pointer to the first byte of the security control field in @p p_frame.
* @returns NULL if the security control cannot be retrieved (that is, security is not enabled).
*
*/
const uint8_t * nrf_802154_frame_parser_sec_ctrl_get(const uint8_t * p_frame);
/**
* @brief Get offset of the first byte after addressing fields in MHR.
* @brief Gets the offset of the first byte after the addressing fields in MHR.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of the first byte after addressing fields in MHR.
* @returns Offset in bytes of the first byte after the addressing fields in MHR.
*/
uint8_t nrf_802154_frame_parser_addressing_end_offset_get(const uint8_t * p_frame);
/**
* @brief Get offset of security control field in provided frame.
* @brief Gets the offset of the security control field in the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of security control field including one byte of frame length.
* Zero if security control cannot be retrieved (security not enabled).
* @returns Offset in bytes of the security control field, including one byte of the frame length.
* @returns Zero if the security control cannot be retrieved (that is, security is not enabled).
*
*/
uint8_t nrf_802154_frame_parser_sec_ctrl_offset_get(const uint8_t * p_frame);
/**
* @brief Get key identifier field in provided frame.
* @brief Gets the key identifier field in the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of key identifier field in @p p_frame.
* NULL if key identifier cannot be retrieved (security not enabled).
* @returns Pointer to the first byte of the key identifier field in @p p_frame.
* @returns NULL if the key identifier cannot be retrieved (that is, security is not enabled).
*
*/
const uint8_t * nrf_802154_frame_parser_key_id_get(const uint8_t * p_frame);
/**
* @brief Get offset of key identifier field in provided frame.
* @brief Gets the offset of the key identifier field in the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of key identifier field including one byte of frame length.
* Zero if key identifier cannot be retrieved (security not enabled).
* @returns Offset in bytes of the key identifier field, including one byte of the frame length.
* @returns Zero if the key identifier cannot be retrieved (that is, security is not enabled).
*
*/
uint8_t nrf_802154_frame_parser_key_id_offset_get(const uint8_t * p_frame);
/**
* @brief Determine if sequence number suppression bit is set.
* @brief Determines if the sequence number suppression bit is set.
*
* @param[in] p_frame Pointer to a frame.
*
* @retval true If sequence number suppression bit is set.
* @retval false Otherwise.
* @retval true Sequence number suppression bit is set.
* @retval false Sequence number suppression bit is not set.
*
*/
bool nrf_802154_frame_parser_dsn_suppress_bit_is_set(const uint8_t * p_frame);
/**
* @brief Determine if IE present bit is set.
* @brief Determines if the IE present bit is set.
*
* @param[in] p_frame Pointer to a frame.
*
* @retval true If IE present bit is set.
* @retval false Otherwise.
* @retval true IE present bit is set.
* @retval false IE present bit is not set.
*
*/
bool nrf_802154_frame_parser_ie_present_bit_is_set(const uint8_t * p_frame);
/**
* @brief Get IE header field in provided frame.
* @brief Determines if the Ack Request (AR) bit is set.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of IE header field in @p p_frame.
* NULL if IE header cannot be retrieved (IE not present).
* @retval true AR bit is set.
* @retval false AR bit is not set.
*
*/
bool nrf_802154_frame_parser_ar_bit_is_set(const uint8_t * p_frame);
/**
* @brief Gets the IE header field in the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Pointer to the first byte of the IE header field in @p p_frame.
* @returns NULL if the IE header cannot be retrieved (that is, the IE header is not present).
*
*/
const uint8_t * nrf_802154_frame_parser_ie_header_get(const uint8_t * p_frame);
/**
* @brief Get offset of IE header field in provided frame.
* @brief Gets the offset of the IE header field in the provided frame.
*
* @param[in] p_frame Pointer to a frame.
*
* @returns Offset in bytes of IE header field including one byte of frame length.
* Zero if IE header cannot be retrieved (IE not present).
* @returns Offset in bytes of the IE header field, including one byte of the frame length.
* @returns Zero if the IE header cannot be retrieved (that is, the IE header is not present).
*
*/
uint8_t nrf_802154_frame_parser_ie_header_offset_get(const uint8_t * p_frame);
@@ -118,7 +118,7 @@ static void timeout_timer_stop(void)
// this function.
__DMB();
nrf_802154_timer_sched_remove(&m_timer);
nrf_802154_timer_sched_remove(&m_timer, NULL);
}
void nrf_802154_ack_timeout_time_set(uint32_t time)
+40 -3
View File
@@ -380,6 +380,18 @@ bool nrf_802154_transmit_raw_at(const uint8_t * p_data,
return result;
}
bool nrf_802154_transmit_at_cancel(void)
{
bool result;
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_TRANSMIT_AT_CANCEL);
result = nrf_802154_delayed_trx_transmit_cancel();
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TRANSMIT_AT_CANCEL);
return result;
}
bool nrf_802154_receive_at(uint32_t t0,
uint32_t dt,
uint32_t timeout,
@@ -395,6 +407,18 @@ bool nrf_802154_receive_at(uint32_t t0,
return result;
}
bool nrf_802154_receive_at_cancel(void)
{
bool result;
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_RECEIVE_AT_CANCEL);
result = nrf_802154_delayed_trx_receive_cancel();
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RECEIVE_AT_CANCEL);
return result;
}
bool nrf_802154_energy_detection(uint32_t time_us)
{
bool result;
@@ -503,13 +527,21 @@ bool nrf_802154_buffer_free_immediately(uint8_t * p_data)
#endif // NRF_802154_USE_RAW_API
bool nrf_802154_rssi_measure_begin(void)
{
return nrf_802154_request_rssi_measure();
}
int8_t nrf_802154_rssi_last_get(void)
{
uint8_t negative_dbm = nrf_radio_rssi_sample_get();
int8_t result = 0;
negative_dbm = nrf_802154_rssi_sample_corrected_get(negative_dbm);
if (!nrf_802154_request_rssi_measurement_get(&result))
{
result = NRF_802154_RSSI_INVALID;
}
return -(int8_t)negative_dbm;
return result;
}
bool nrf_802154_promiscuous_get(void)
@@ -551,6 +583,11 @@ bool nrf_802154_ack_data_set(const uint8_t * p_addr,
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)
{
return nrf_802154_ack_data_for_addr_clear(p_addr, extended, data_type);
}
void nrf_802154_auto_pending_bit_set(bool enabled)
{
nrf_802154_ack_data_enable(enabled);
File diff suppressed because it is too large Load Diff
@@ -66,7 +66,7 @@ extern "C" {
/**
* @def NRF_802154_CCA_ED_THRESHOLD_DEFAULT
*
* Energy detection threshold used in CCA procedure.
* Energy detection threshold used in the CCA procedure.
*
*/
#ifndef NRF_802154_CCA_ED_THRESHOLD_DEFAULT
@@ -76,7 +76,7 @@ extern "C" {
/**
* @def NRF_802154_CCA_CORR_THRESHOLD_DEFAULT
*
* Correlator threshold used in CCA procedure.
* Correlator threshold used in the CCA procedure.
*
*/
#ifndef NRF_802154_CCA_CORR_THRESHOLD_DEFAULT
@@ -86,7 +86,7 @@ extern "C" {
/**
* @def NRF_802154_CCA_CORR_LIMIT_DEFAULT
*
* Correlator limit used in CCA procedure.
* Correlator limit used in the CCA procedure.
*
*/
#ifndef NRF_802154_CCA_CORR_LIMIT_DEFAULT
@@ -96,9 +96,11 @@ extern "C" {
/**
* @def NRF_802154_INTERNAL_RADIO_IRQ_HANDLING
*
* If the driver should internally handle the RADIO IRQ.
* If the driver is used in an OS, the RADIO IRQ may be handled by the OS and passed to
* the driver by @ref nrf_802154_radio_irq_handler. In this case, internal handling should be disabled.
* If the driver is expected to internally handle the RADIO IRQ.
* If the driver is used in an OS, the RADIO IRQ can be handled by the OS and passed to
* the driver by @ref nrf_802154_radio_irq_handler.
* In this case, the internal handling must be disabled.
*
*/
#ifndef NRF_802154_INTERNAL_RADIO_IRQ_HANDLING
@@ -115,8 +117,7 @@ extern "C" {
* @def NRF_802154_IRQ_PRIORITY
*
* Interrupt priority for RADIO peripheral.
* Keep IRQ priority high (low number) to prevent losing frames due to
* preemption.
* Keep the IRQ priority high (low number) to prevent losing frames due to preemption.
*
*/
#ifndef NRF_802154_IRQ_PRIORITY
@@ -126,7 +127,7 @@ extern "C" {
/**
* @def NRF_802154_TIMER_INSTANCE
*
* Timer instance used by the driver for ACK IFS and by the FEM module.
* The timer instance used both by the driver for ACK IFS and by the FEM module.
*
*/
#ifndef NRF_802154_TIMER_INSTANCE
@@ -136,9 +137,9 @@ extern "C" {
/**
* @def NRF_802154_COUNTER_TIMER_INSTANCE
*
* Timer instance used by the driver for detecting when PSDU is being received.
* The timer instance used by the driver for detecting when PSDU is being received.
*
* @note This configuration is used only when NRF_RADIO_EVENT_BCMATCH event handling is disabled
* @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_COUNTER_TIMER_INSTANCE
@@ -148,7 +149,7 @@ extern "C" {
/**
* @def NRF_802154_SWI_EGU_INSTANCE
*
* SWI EGU instance used by the driver to synchronize PPIs and for requests and notifications if
* 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.
@@ -167,7 +168,7 @@ extern "C" {
/**
* @def NRF_802154_SWI_IRQ_HANDLER
*
* SWI EGU IRQ handler used by the driver for requests and notifications if SWI is in use.
* 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.
*
@@ -179,7 +180,7 @@ extern "C" {
/**
* @def NRF_802154_SWI_IRQN
*
* SWI EGU IRQ number used by the driver for requests and notifications if SWI is in use.
* 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.
*
@@ -191,7 +192,7 @@ extern "C" {
/**
* @def NRF_802154_SWI_PRIORITY
*
* Priority of software interrupt used for requests and notifications.
* The priority of software interrupt used for requests and notifications.
*
*/
#ifndef NRF_802154_SWI_PRIORITY
@@ -201,10 +202,10 @@ extern "C" {
/**
* @def NRF_802154_USE_RAW_API
*
* When this flag is set, RAW API is available for the MAC layer. It is recommended to use RAW API
* because it provides more optimized functions.
* When this flag is set, the RAW API is available for the MAC layer. It is recommended to use
* the RAW API because it provides more optimized functions.
*
* @note If RAW API is not available for the MAC layer, only less optimized functions performing
* @note If the RAW API is not available for the MAC layer, only less optimized functions performing
* copy are available.
*
*/
@@ -215,7 +216,7 @@ extern "C" {
/**
* @def NRF_802154_PENDING_SHORT_ADDRESSES
*
* Number of slots containing short addresses of nodes for which pending data is stored.
* The number of slots containing short addresses of nodes for which the pending data is stored.
*
*/
#ifndef NRF_802154_PENDING_SHORT_ADDRESSES
@@ -225,7 +226,7 @@ extern "C" {
/**
* @def NRF_802154_PENDING_EXTENDED_ADDRESSES
*
* Number of slots containing extended addresses of nodes for which pending data is stored.
* The number of slots containing extended addresses of nodes for which the pending data is stored.
*
*/
#ifndef NRF_802154_PENDING_EXTENDED_ADDRESSES
@@ -235,7 +236,7 @@ extern "C" {
/**
* @def NRF_802154_RX_BUFFERS
*
* Number of buffers in receive queue.
* The number of buffers in the receive queue.
*
*/
#ifndef NRF_802154_RX_BUFFERS
@@ -245,9 +246,9 @@ extern "C" {
/**
* @def NRF_802154_DISABLE_BCC_MATCHING
*
* Setting this flag disables NRF_RADIO_EVENT_BCMATCH handling, and therefore address filtering
* during frame reception. With this flag set to 1, address filtering is done after receiving
* a frame, during NRF_RADIO_EVENT_END handling.
* Setting this flag disables NRF_RADIO_EVENT_BCMATCH handling, and therefore the address filtering
* 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.
*
*/
#ifndef NRF_802154_DISABLE_BCC_MATCHING
@@ -257,7 +258,7 @@ extern "C" {
/**
* @def NRF_802154_NOTIFY_CRCERROR
*
* With this flag set to 1, CRC errors are notified to upper layers. This requires an interrupt
* With this flag set to 1, the CRC errors are notified to upper layers. This requires an interrupt
* handler to be used.
*
*/
@@ -268,10 +269,10 @@ extern "C" {
/**
* @def NRF_802154_FRAME_TIMESTAMP_ENABLED
*
* If timestamps should be added to received frames.
* If timestamps are to be added to the frames received.
* Enabling this feature enables the functions @ref nrf_802154_received_timsestamp_raw,
* @ref nrf_802154_received_timestamp, @ref nrf_802154_transmitted_timestamp_raw, and
* @ref nrf_802154_transmitted_timestamp, which add timestamps to received frames.
* @ref nrf_802154_transmitted_timestamp, which add timestamps to the frames received.
*
*/
#ifndef NRF_802154_FRAME_TIMESTAMP_ENABLED
@@ -281,7 +282,7 @@ extern "C" {
/**
* @def NRF_802154_DELAYED_TRX_ENABLED
*
* If delayed transmission and receive window features are available.
* If the delayed transmission and the receive window features are available.
*
*/
#ifndef NRF_802154_DELAYED_TRX_ENABLED
@@ -297,20 +298,20 @@ extern "C" {
/**
* @def NRF_802154_CLOCK_IRQ_PRIORITY
*
* Priority of clock interrupt used in standalone clock driver implementation.
* 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 10
#define NRF_802154_CLOCK_IRQ_PRIORITY 7
#endif
/**
* @def NRF_802154_CLOCK_LFCLK_SOURCE
*
* Low-frequency clock source used in standalone clock driver implementation.
* 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.
@@ -329,10 +330,10 @@ extern "C" {
/**
* @def NRF_802154_RTC_IRQ_PRIORITY
*
* Priority of RTC interrupt used in standalone timer driver implementation.
* 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.
* @note This configuration is only applicable for the Low Power Timer Abstraction Layer
* implementation in nrf_802154_lp_timer_nodrv.c.
*
*/
#ifndef NRF_802154_RTC_IRQ_PRIORITY
@@ -342,10 +343,10 @@ extern "C" {
/**
* @def NRF_802154_RTC_INSTANCE
*
* RTC instance used in standalone timer driver implementation.
* 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.
* @note This configuration is only applicable for the Low Power Timer Abstraction Layer
* implementation in nrf_802154_lp_timer_nodrv.c.
*
*/
#ifndef NRF_802154_RTC_INSTANCE
@@ -361,7 +362,7 @@ extern "C" {
/**
* @def NRF_802154_RTC_IRQ_HANDLER
*
* RTC interrupt handler name used in standalone timer driver implementation.
* 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.
@@ -380,7 +381,7 @@ extern "C" {
/**
* @def NRF_802154_RTC_IRQN
*
* RTC Interrupt number used in standalone timer driver implementation.
* 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.
@@ -405,8 +406,8 @@ extern "C" {
/**
* @def NRF_802154_CSMA_CA_ENABLED
*
* If CSMA-CA should be enabled by the driver. Disabling CSMA-CA improves
* driver performance.
* If CSMA-CA is to be enabled by the driver. Disabling CSMA-CA improves
* the driver performance.
*
*/
#ifndef NRF_802154_CSMA_CA_ENABLED
@@ -417,7 +418,7 @@ extern "C" {
* @def NRF_802154_CSMA_CA_MIN_BE
*
* The minimum value of the backoff exponent (BE) in the CSMA-CA algorithm
* (IEEE 802.15.4-2015: 6.2.5.1).
* (see IEEE 802.15.4-2015: 6.2.5.1).
*
*/
#ifndef NRF_802154_CSMA_CA_MIN_BE
@@ -428,7 +429,7 @@ extern "C" {
* @def NRF_802154_CSMA_CA_MAX_BE
*
* The maximum value of the backoff exponent, BE, in the CSMA-CA algorithm
* (IEEE 802.15.4-2015: 6.2.5.1).
* (see IEEE 802.15.4-2015: 6.2.5.1).
*
*/
#ifndef NRF_802154_CSMA_CA_MAX_BE
@@ -449,17 +450,18 @@ extern "C" {
/**
* @def NRF_802154_CSMA_CA_WAIT_FOR_TIMESLOT
*
* Indicates whether the CSMA-CA algorithm waits for an available timeslot before it performs the CCA procedure.
* Indicates whether the CSMA-CA algorithm waits for an available timeslot before it performs
* the CCA procedure.
*
* @note When this option is enabled, the CSMA-CA procedure may be synchronized with timeslots of
* other protocols. It decreases robustness of the CSMA-CA procedure and is not recommended.
* This option may be used as a workaround to problems with higher layers that do not correctly handle
* multiple CHANNEL_BUSY errors in a row. This potentially problematic situation may
* happen during activity of other protocols.
* @note When this option is enabled, the CSMA-CA procedure can be synchronized with timeslots of
* other protocols. This decreases the robustness of the CSMA-CA procedure. On the other hand,
* enabling this function increases the performance of multi-protocol applications, especially
* when protocols other than 802.15.4 use much of the radio time (like the BLE scanning
* operation).
*
*/
#ifndef NRF_802154_CSMA_CA_WAIT_FOR_TIMESLOT
#define NRF_802154_CSMA_CA_WAIT_FOR_TIMESLOT 0
#define NRF_802154_CSMA_CA_WAIT_FOR_TIMESLOT 1
#endif
/**
@@ -471,7 +473,7 @@ extern "C" {
/**
* @def NRF_802154_ACK_TIMEOUT_ENABLED
*
* If the ACK timeout feature should be enabled in the driver.
* Indicates whether the ACK timeout feature is to be enabled in the driver.
*
*/
#ifndef NRF_802154_ACK_TIMEOUT_ENABLED
@@ -481,7 +483,7 @@ extern "C" {
/**
* @def NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT
*
* Default timeout in us for the ACK timeout feature.
* The default timeout in microseconds (us) for the ACK timeout feature.
*
*/
#ifndef NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT
@@ -491,7 +493,7 @@ extern "C" {
/**
* @def NRF_802154_ACK_TIMEOUT_DEFAULT_TIMEOUT
*
* Default time-out in us for the precise ACK time-out feature.
* The default timeout in microseconds (us) for the precise ACK timeout feature.
*
*/
#ifndef NRF_802154_PRECISE_ACK_TIMEOUT_DEFAULT_TIMEOUT
@@ -501,7 +503,7 @@ extern "C" {
/**
* @def NRF_802154_MAX_ACK_IE_SIZE
*
* Maximum supported size of 802.15.4-2015 IE header and content fields in an Enh-Ack.
* The maximum supported size of the 802.15.4-2015 IE header and content fields in an Enh-Ack.
*
*/
#ifndef NRF_802154_MAX_ACK_IE_SIZE
@@ -517,10 +519,10 @@ extern "C" {
/**
* @def NRF_802154_TX_STARTED_NOTIFY_ENABLED
*
* If notifications of started transmissions should be enabled in the driver.
* Indicates whether the notifications of the started transmissions are to be enabled in the driver.
*
* @note This feature is enabled by default if the ACK timeout feature or CSMA-CA is enabled.
* These features depend on notifications of transmission start.
* These features depend on the notifications of the transmission start.
*/
#ifndef NRF_802154_TX_STARTED_NOTIFY_ENABLED
#if NRF_802154_ACK_TIMEOUT_ENABLED || NRF_802154_CSMA_CA_ENABLED
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contains constant values definitions used by nRF 802.15.4 driver.
* @brief Module that contains definitions of constant values used by the nRF 802.15.4 driver.
*
*/
@@ -39,114 +39,114 @@
#include <stdint.h>
#include "nrf_802154_config.h"
#define ACK_HEADER_WITH_PENDING 0x12 ///< First byte of ACK frame containing pending bit.
#define ACK_HEADER_WITHOUT_PENDING 0x02 ///< First byte of ACK frame without pending bit.
#define ACK_HEADER_WITH_PENDING 0x12 ///< The first byte of an ACK frame containing a pending bit.
#define ACK_HEADER_WITHOUT_PENDING 0x02 ///< The first byte of an ACK frame without a pending bit.
#define ACK_REQUEST_OFFSET 1 ///< Byte containing Ack request bit (+1 for frame length byte).
#define ACK_REQUEST_BIT (1 << 5) ///< Ack request bit.
#define ACK_REQUEST_OFFSET 1 ///< Byte containing the ACK request bit (+1 for the frame length byte).
#define ACK_REQUEST_BIT (1 << 5) ///< ACK request bit.
#define DEST_ADDR_TYPE_OFFSET 2 ///< Byte containing destination address type (+1 for frame length byte).
#define DEST_ADDR_TYPE_MASK 0x0c ///< Mask of bits containing destination address type.
#define DEST_ADDR_TYPE_EXTENDED 0x0c ///< Bits containing extended destination address type.
#define DEST_ADDR_TYPE_NONE 0x00 ///< Bits containing not present destination address type.
#define DEST_ADDR_TYPE_SHORT 0x08 ///< Bits containing short destination address type.
#define DEST_ADDR_OFFSET 6 ///< Offset of destination address in Data frame (+1 for frame length byte).
#define DEST_ADDR_TYPE_OFFSET 2 ///< Byte containing the destination address type (+1 for the frame length byte).
#define DEST_ADDR_TYPE_MASK 0x0c ///< Mask of bits containing the destination address type.
#define DEST_ADDR_TYPE_EXTENDED 0x0c ///< Bits containing the extended destination address type.
#define DEST_ADDR_TYPE_NONE 0x00 ///< Bits containing a not-present destination address type.
#define DEST_ADDR_TYPE_SHORT 0x08 ///< Bits containing the short destination address type.
#define DEST_ADDR_OFFSET 6 ///< Offset of the destination address in the Data frame (+1 for the frame length byte).
#define DSN_OFFSET 3 ///< Byte containing DSN value (+1 for frame length byte).
#define DSN_SUPPRESS_OFFSET 2 ///< Byte containing DSN suppression field.
#define DSN_SUPPRESS_BIT 0x01 ///< Bits containing DSN suppression field.
#define DSN_OFFSET 3 ///< Byte containing the DSN value (+1 for the frame length byte).
#define DSN_SUPPRESS_OFFSET 2 ///< Byte containing the DSN suppression field.
#define DSN_SUPPRESS_BIT 0x01 ///< Bits containing the DSN suppression field.
#define FRAME_COUNTER_SUPPRESS_BIT 0x20 ///< Bit containing Frame Counter Suppression field.
#define FRAME_COUNTER_SUPPRESS_BIT 0x20 ///< Bit containing the Frame Counter Suppression field.
#define FRAME_PENDING_OFFSET 1 ///< Byte containing pending bit (+1 for frame length byte).
#define FRAME_PENDING_OFFSET 1 ///< Byte containing a pending bit (+1 for the frame length byte).
#define FRAME_PENDING_BIT (1 << 4) ///< Pending bit.
#define FRAME_TYPE_OFFSET 1 ///< Byte containing frame type bits (+1 for frame length byte).
#define FRAME_TYPE_MASK 0x07 ///< Mask of bits containing frame type.
#define FRAME_TYPE_ACK 0x02 ///< Bits containing ACK frame type.
#define FRAME_TYPE_BEACON 0x00 ///< Bits containing Beacon frame type.
#define FRAME_TYPE_COMMAND 0x03 ///< Bits containing Command frame type.
#define FRAME_TYPE_DATA 0x01 ///< Bits containing Data frame type.
#define FRAME_TYPE_EXTENDED 0x07 ///< Bits containing Extended frame type.
#define FRAME_TYPE_FRAGMENT 0x06 ///< Bits containing Fragment or Frak frame type.
#define FRAME_TYPE_MULTIPURPOSE 0x05 ///< Bits containing Multipurpose frame type.
#define FRAME_TYPE_OFFSET 1 ///< Byte containing the frame type bits (+1 for the frame length byte).
#define FRAME_TYPE_MASK 0x07 ///< Mask of bits containing the frame type.
#define FRAME_TYPE_ACK 0x02 ///< Bits containing the ACK frame type.
#define FRAME_TYPE_BEACON 0x00 ///< Bits containing the Beacon frame type.
#define FRAME_TYPE_COMMAND 0x03 ///< Bits containing the Command frame type.
#define FRAME_TYPE_DATA 0x01 ///< Bits containing the Data frame type.
#define FRAME_TYPE_EXTENDED 0x07 ///< Bits containing the Extended frame type.
#define FRAME_TYPE_FRAGMENT 0x06 ///< Bits containing the Fragment or the Frak frame type.
#define FRAME_TYPE_MULTIPURPOSE 0x05 ///< Bits containing the Multipurpose frame type.
#define FRAME_VERSION_OFFSET 2 ///< Byte containing frame version bits (+1 for frame length byte).
#define FRAME_VERSION_MASK 0x30 ///< Mask of bits containing frame version.
#define FRAME_VERSION_0 0x00 ///< Bits containing frame version 0b00.
#define FRAME_VERSION_1 0x10 ///< Bits containing frame version 0b01.
#define FRAME_VERSION_2 0x20 ///< Bits containing frame version 0b10.
#define FRAME_VERSION_3 0x30 ///< Bits containing frame version 0b11.
#define FRAME_VERSION_OFFSET 2 ///< Byte containing the frame version bits (+1 for the frame length byte).
#define FRAME_VERSION_MASK 0x30 ///< Mask of bits containing the frame version.
#define FRAME_VERSION_0 0x00 ///< Bits containing the frame version 0b00.
#define FRAME_VERSION_1 0x10 ///< Bits containing the frame version 0b01.
#define FRAME_VERSION_2 0x20 ///< Bits containing the frame version 0b10.
#define FRAME_VERSION_3 0x30 ///< Bits containing the frame version 0b11.
#define IE_HEADER_LENGTH_MASK 0x3f ///< Mask of bits containing length of an IE header content.
#define IE_PRESENT_OFFSET 2 ///< Byte containing IE Present bit.
#define IE_PRESENT_BIT 0x02 ///< Bits containing IE Present field.
#define IE_HEADER_LENGTH_MASK 0x3f ///< Mask of bits containing the length of an IE header content.
#define IE_PRESENT_OFFSET 2 ///< Byte containing the IE Present bit.
#define IE_PRESENT_BIT 0x02 ///< Bits containing the IE Present field.
#define KEY_ID_MODE_MASK 0x18 ///< Mask of bits containing Key Identifier Mode in Security Control field.
#define KEY_ID_MODE_0 0 ///< Bits containing 0x00 Key Identifier Mode.
#define KEY_ID_MODE_1 0x08 ///< Bits containing 0x01 Key Identifier Mode.
#define KEY_ID_MODE_2 0x10 ///< Bits containing 0x10 Key Identifier Mode.
#define KEY_ID_MODE_3 0x18 ///< Bits containing 0x11 Key Identifier Mode.
#define KEY_ID_MODE_MASK 0x18 ///< Mask of bits containing Key Identifier Mode in the Security Control field.
#define KEY_ID_MODE_0 0 ///< Bits containing the 0x00 Key Identifier Mode.
#define KEY_ID_MODE_1 0x08 ///< Bits containing the 0x01 Key Identifier Mode.
#define KEY_ID_MODE_2 0x10 ///< Bits containing the 0x10 Key Identifier Mode.
#define KEY_ID_MODE_3 0x18 ///< Bits containing the 0x11 Key Identifier Mode.
#define PAN_ID_COMPR_OFFSET 1 ///< Byte containing Pan Id compression bit (+1 for frame length byte).
#define PAN_ID_COMPR_MASK 0x40 ///< Pan Id compression bit.
#define PAN_ID_COMPR_OFFSET 1 ///< Byte containing the PAN ID compression bit (+1 for the frame length byte).
#define PAN_ID_COMPR_MASK 0x40 ///< PAN ID compression bit.
#define PAN_ID_OFFSET 4 ///< Offset of Pan Id in Data frame (+1 for frame length byte).
#define PAN_ID_OFFSET 4 ///< Offset of PAN ID in the Data frame (+1 for the frame length byte).
#define PHR_OFFSET 0 ///< Offset of the phy header in a frame
#define PHR_OFFSET 0 ///< Offset of the PHY header in a frame.
#define SECURITY_ENABLED_OFFSET 1 ///< Byte containing Security enabled bit.
#define SECURITY_ENABLED_BIT 0x08 ///< Bits containing Security enabled field.
#define SECURITY_LEVEL_MASK 0x07 ///< Mask of bits containing Security level field.
#define SECURITY_LEVEL_MIC_32 0x01 ///< Bits containing 32-bit Message Integrity Code (0b001).
#define SECURITY_LEVEL_MIC_64 0x02 ///< Bits containing 64-bit Message Integrity Code (0b010).
#define SECURITY_LEVEL_MIC_128 0x03 ///< Bits containing 128-bit Message Integrity Code (0b011).
#define SECURITY_LEVEL_ENC_MIC_32 0x05 ///< Bits containing 32-bit Encrypted Message Integrity Code (0b101).
#define SECURITY_LEVEL_ENC_MIC_64 0x06 ///< Bits containing 64-bit Encrypted Message Integrity Code (0b110).
#define SECURITY_LEVEL_ENC_MIC_128 0x07 ///< Bits containing 128-bit Encrypted Message Integrity Code (0b111).
#define SECURITY_ENABLED_OFFSET 1 ///< Byte containing the Security Enabled bit.
#define SECURITY_ENABLED_BIT 0x08 ///< Bits containing the Security Enabled field.
#define SECURITY_LEVEL_MASK 0x07 ///< Mask of bits containing the Security level field.
#define SECURITY_LEVEL_MIC_32 0x01 ///< Bits containing the 32-bit Message Integrity Code (0b001).
#define SECURITY_LEVEL_MIC_64 0x02 ///< Bits containing the 64-bit Message Integrity Code (0b010).
#define SECURITY_LEVEL_MIC_128 0x03 ///< Bits containing the 128-bit Message Integrity Code (0b011).
#define SECURITY_LEVEL_ENC_MIC_32 0x05 ///< Bits containing the 32-bit Encrypted Message Integrity Code (0b101).
#define SECURITY_LEVEL_ENC_MIC_64 0x06 ///< Bits containing the 64-bit Encrypted Message Integrity Code (0b110).
#define SECURITY_LEVEL_ENC_MIC_128 0x07 ///< Bits containing the 128-bit Encrypted Message Integrity Code (0b111).
#define SRC_ADDR_TYPE_EXTENDED 0xc0 ///< Bits containing extended source address type.
#define SRC_ADDR_TYPE_NONE 0x00 ///< Bits containing not present source address type.
#define SRC_ADDR_TYPE_MASK 0xc0 ///< Mask of bits containing source address type.
#define SRC_ADDR_TYPE_OFFSET 2 ///< Byte containing source address type (+1 for frame length byte).
#define SRC_ADDR_TYPE_SHORT 0x80 ///< Bits containing short source address type.
#define SRC_ADDR_TYPE_EXTENDED 0xc0 ///< Bits containing the extended source address type.
#define SRC_ADDR_TYPE_NONE 0x00 ///< Bits containing a not-present source address type.
#define SRC_ADDR_TYPE_MASK 0xc0 ///< Mask of bits containing the source address type.
#define SRC_ADDR_TYPE_OFFSET 2 ///< Byte containing the source address type (+1 for the frame length byte).
#define SRC_ADDR_TYPE_SHORT 0x80 ///< Bits containing the short source address type.
#define SRC_ADDR_OFFSET_SHORT_DST 8 ///< Offset of source address in Data frame if destination address is short.
#define SRC_ADDR_OFFSET_EXTENDED_DST 14 ///< Offset of source address in Data frame if destination address is extended.
#define SRC_ADDR_OFFSET_SHORT_DST 8 ///< Offset of the source address in the Data frame if the destination address is short.
#define SRC_ADDR_OFFSET_EXTENDED_DST 14 ///< Offset of the source address in the Data frame if the destination address is extended.
#define DSN_SIZE 1 ///< Size of Sequence Number field.
#define FCF_SIZE 2 ///< Size of FCF field.
#define FCS_SIZE 2 ///< Size of FCS field.
#define FRAME_COUNTER_SIZE 4 ///< Size of Frame Counter field.
#define IE_HEADER_SIZE 4 ///< Size of obligatory IE Header field elements, including header termination.
#define IMM_ACK_LENGTH 5 ///< Length of ACK frame.
#define KEY_ID_MODE_1_SIZE 1 ///< Size of 0x01 Key Identifier Mode field.
#define KEY_ID_MODE_2_SIZE 5 ///< Size of 0x10 Key Identifier Mode field.
#define KEY_ID_MODE_3_SIZE 9 ///< Size of 0x11 Key Identifier Mode field.
#define MAX_PACKET_SIZE 127 ///< Maximum size of radio packet.
#define MIC_32_SIZE 4 ///< Size of MIC with MIC-32 and ENC-MIC-32 security attributes.
#define MIC_64_SIZE 8 ///< Size of MIC with MIC-64 and ENC-MIC-64 security attributes.
#define MIC_128_SIZE 16 ///< Size of MIC with MIC-128 and ENC-MIC-128 security attributes.
#define PAN_ID_SIZE 2 ///< Size of Pan Id.
#define PHR_SIZE 1 ///< Size of PHR field.
#define SECURITY_CONTROL_SIZE 1 ///< Size of Security Control field.
#define DSN_SIZE 1 ///< Size of the Sequence Number field.
#define FCF_SIZE 2 ///< Size of the FCF field.
#define FCS_SIZE 2 ///< Size of the FCS field.
#define FRAME_COUNTER_SIZE 4 ///< Size of the Frame Counter field.
#define IE_HEADER_SIZE 4 ///< Size of the obligatory IE Header field elements, including the header termination.
#define IMM_ACK_LENGTH 5 ///< Length of the ACK frame.
#define KEY_ID_MODE_1_SIZE 1 ///< Size of the 0x01 Key Identifier Mode field.
#define KEY_ID_MODE_2_SIZE 5 ///< Size of the 0x10 Key Identifier Mode field.
#define KEY_ID_MODE_3_SIZE 9 ///< Size of the 0x11 Key Identifier Mode field.
#define MAX_PACKET_SIZE 127 ///< Maximum size of the radio packet.
#define MIC_32_SIZE 4 ///< Size of MIC with the MIC-32 and ENC-MIC-32 security attributes.
#define MIC_64_SIZE 8 ///< Size of MIC with the MIC-64 and ENC-MIC-64 security attributes.
#define MIC_128_SIZE 16 ///< Size of MIC with the MIC-128 and ENC-MIC-128 security attributes.
#define PAN_ID_SIZE 2 ///< Size of the PAN ID.
#define PHR_SIZE 1 ///< Size of the PHR field.
#define SECURITY_CONTROL_SIZE 1 ///< Size of the Security Control field.
#define EXTENDED_ADDRESS_SIZE 8 ///< Size of Extended Mac Address.
#define SHORT_ADDRESS_SIZE 2 ///< Size of Short Mac Address.
#define EXTENDED_ADDRESS_SIZE 8 ///< Size of the Extended Mac Address.
#define SHORT_ADDRESS_SIZE 2 ///< Size of the Short Mac Address.
#define TURNAROUND_TIME 192UL ///< aTurnaroundTime [us].
#define CCA_TIME 128UL ///< aCcaTime [us].
#define UNIT_BACKOFF_PERIOD (TURNAROUND_TIME + CCA_TIME) ///< aUnitBackoffPeriod [us].
#define TURNAROUND_TIME 192UL ///< RX-to-TX or TX-to-RX turnaround time (aTurnaroundTime), in microseconds (us).
#define CCA_TIME 128UL ///< Time required to perform CCA detection (aCcaTime), in microseconds (us).
#define UNIT_BACKOFF_PERIOD (TURNAROUND_TIME + CCA_TIME) ///< Number of symbols in the basic time period used by CSMA-CA algorithm (aUnitBackoffPeriod), in (us).
#define PHY_US_PER_SYMBOL 16 ///< Duration of a single symbol in microseconds [us].
#define PHY_US_PER_SYMBOL 16 ///< Duration of a single symbol in microseconds (us).
#define PHY_SYMBOLS_PER_OCTET 2 ///< Number of symbols in a single byte (octet).
#define PHY_SHR_SYMBOLS 10 ///< Number of symbols in Synchronization Header (SHR).
#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 EDSAMPLE register.
#define ED_RESULT_FACTOR 4 ///< Factor needed to calculate ED result based on data from RADIO peripheral.
#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 BROADCAST_ADDRESS ((uint8_t[SHORT_ADDRESS_SIZE]) {0xff, 0xff}) ///< Broadcast short address.
typedef enum
{
@@ -52,8 +52,10 @@
#include "nrf_802154_revision.h"
#include "nrf_802154_rssi.h"
#include "nrf_802154_rx_buffer.h"
#include "nrf_802154_utils.h"
#include "nrf_802154_timer_coord.h"
#include "nrf_802154_types.h"
#include "nrf_802154_utils.h"
#include "nrf_egu.h"
#include "nrf_ppi.h"
#include "nrf_radio.h"
@@ -197,11 +199,12 @@ typedef struct
#endif // !NRF_802154_DISABLE_BCC_MATCHING
#if NRF_802154_TX_STARTED_NOTIFY_ENABLED
bool tx_started : 1; ///< If requested transmission has started.
bool tx_started : 1; ///< If the requested transmission has started.
#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 current driver state.
static nrf_802154_flags_t m_flags; ///< Flags used to store the current driver state.
static volatile bool m_rsch_timeslot_is_granted; ///< State of the RSCH timeslot.
@@ -230,9 +233,27 @@ static void rx_flags_clear(void)
#endif // !NRF_802154_DISABLE_BCC_MATCHING
}
/** Get result of last RSSI measurement.
/** 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))
{
// Intentionally empty: This function is called from a critical section.
// WFE would not be waken up by a RADIO event.
}
}
/** Get the result of the last RSSI measurement.
*
* @returns Result of last RSSI measurement [dBm].
* @returns Result of the last RSSI measurement in dBm.
*/
static int8_t rssi_last_measurement_get(void)
{
@@ -307,7 +328,9 @@ static void transmit_started_notify(void)
/** Notify that reception of a frame has started. */
static void receive_started_notify(void)
{
nrf_802154_core_hooks_rx_started();
const uint8_t * p_frame = mp_current_rx_buffer->data;
nrf_802154_core_hooks_rx_started(p_frame);
}
#endif
@@ -485,7 +508,7 @@ static void channel_set(uint8_t channel)
*/
static bool ack_is_requested(const uint8_t * p_frame)
{
return (p_frame[ACK_REQUEST_OFFSET] & ACK_REQUEST_BIT) ? true : false;
return nrf_802154_frame_parser_ar_bit_is_set(p_frame);
}
/***************************************************************************************************
@@ -565,6 +588,9 @@ static void nrf_radio_reset(void)
/** Initialize interrupts for radio peripheral. */
static void irq_init(void)
{
#if !NRF_IS_IRQ_PRIORITY_ALLOWED(NRF_802154_IRQ_PRIORITY)
#error NRF_802154_IRQ_PRIORITY value out of the allowed range.
#endif
NVIC_SetPriority(RADIO_IRQn, NRF_802154_IRQ_PRIORITY);
NVIC_ClearPendingIRQ(RADIO_IRQn);
}
@@ -1360,6 +1386,8 @@ static void rx_init(bool disabled_was_triggered)
// 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());
@@ -1738,10 +1766,11 @@ static void cont_prec_denied(void)
{
irq_deinit();
nrf_radio_reset();
nrf_fem_control_pin_clear();
nrf_802154_timer_coord_stop();
}
nrf_fem_control_pin_clear();
nrf_802154_timer_coord_stop();
result = current_operation_terminate(NRF_802154_TERM_802154, REQ_ORIG_RSCH, false);
assert(result);
(void)result;
@@ -1925,6 +1954,8 @@ static void irq_crcok_state_rx(void)
uint32_t ints_to_disable = 0;
uint32_t ints_to_enable = 0;
m_flags.rssi_started = true;
#if NRF_802154_DISABLE_BCC_MATCHING
uint8_t num_data_bytes = PHR_SIZE + FCF_SIZE;
uint8_t prev_num_data_bytes = 0;
@@ -2775,21 +2806,12 @@ bool nrf_802154_core_sleep(nrf_802154_term_t term_lvl)
{
if ((m_state != RADIO_STATE_SLEEP) && (m_state != RADIO_STATE_FALLING_ASLEEP))
{
if (critical_section_can_be_processed_now())
{
result = current_operation_terminate(term_lvl, REQ_ORIG_CORE, true);
result = current_operation_terminate(term_lvl, REQ_ORIG_CORE, true);
if (result)
{
state_set(RADIO_STATE_FALLING_ASLEEP);
falling_asleep_init();
}
}
else
if (result)
{
nrf_radio_reset();
state_set(RADIO_STATE_SLEEP);
sleep_init();
state_set(RADIO_STATE_FALLING_ASLEEP);
falling_asleep_init();
}
}
@@ -3068,6 +3090,57 @@ bool nrf_802154_core_cca_cfg_update(void)
return result;
}
bool nrf_802154_core_rssi_measure(void)
{
bool result = critical_section_enter_and_verify_timeslot_length();
if (result)
{
if (timeslot_is_granted() && (m_state == RADIO_STATE_RX))
{
rssi_measure();
}
else
{
result = false;
}
nrf_802154_critical_section_exit();
}
return result;
}
bool nrf_802154_core_last_rssi_measurement_get(int8_t * p_rssi)
{
bool result = false;
bool rssi_started = m_flags.rssi_started;
bool in_crit_sect = false;
if (rssi_started)
{
in_crit_sect = critical_section_enter_and_verify_timeslot_length();
}
if (rssi_started && in_crit_sect)
{
// 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;
}
}
if (in_crit_sect)
{
nrf_802154_critical_section_exit();
}
return result;
}
#if NRF_802154_INTERNAL_RADIO_IRQ_HANDLING
void RADIO_IRQHandler(void)
#else // NRF_802154_INTERNAL_RADIO_IRQ_HANDLING
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contains core of the nRF IEEE 802.15.4 radio driver.
* @brief Module that contains core of the nRF IEEE 802.15.4 radio driver.
*
*/
@@ -49,47 +49,47 @@ extern "C" {
#endif
/**
* @brief States of nRF 802.15.4 driver.
* @brief States of the nRF 802.15.4 driver.
*/
typedef enum
{
// Sleep
RADIO_STATE_SLEEP, ///< Low power (DISABLED) mode - the only state in which all radio preconditions ane not requested.
RADIO_STATE_FALLING_ASLEEP, ///< Prior entering SLEEP state all radio preconditions are requested.
RADIO_STATE_SLEEP, ///< Low power mode (disabled) - the only state in which all radio preconditions are not requested.
RADIO_STATE_FALLING_ASLEEP, ///< Before entering the sleep state, all radio preconditions are requested.
// Receive
RADIO_STATE_RX, ///< Receiver is enabled and it is receiving frames.
RADIO_STATE_TX_ACK, ///< Received frame and transmitting ACK.
RADIO_STATE_RX, ///< The receiver is enabled and it is receiving frames.
RADIO_STATE_TX_ACK, ///< The frame is received and the ACK is being transmitted.
// Transmit
RADIO_STATE_CCA_TX, ///< Performing CCA followed by frame transmission.
RADIO_STATE_CCA_TX, ///< Performing CCA followed by the frame transmission.
RADIO_STATE_TX, ///< Transmitting data frame (or beacon).
RADIO_STATE_RX_ACK, ///< Receiving ACK after transmitted frame.
RADIO_STATE_RX_ACK, ///< Receiving ACK after the transmitted frame.
// Energy Detection
RADIO_STATE_ED, ///< Performing Energy Detection procedure.
RADIO_STATE_ED, ///< Performing the energy detection procedure.
// CCA
RADIO_STATE_CCA, ///< Performing CCA procedure.
RADIO_STATE_CCA, ///< Performing the CCA procedure.
// Continuous carrier
RADIO_STATE_CONTINUOUS_CARRIER, ///< Emitting continuous carrier wave.
RADIO_STATE_CONTINUOUS_CARRIER, ///< Emitting the continuous carrier wave.
} radio_state_t;
/**
* @brief Initialize 802.15.4 driver core.
* @brief Initializes the 802.15.4 driver core.
*/
void nrf_802154_core_init(void);
/**
* @brief Deinitialize 802.15.4 driver core.
* @brief Deinitializes the 802.15.4 driver core.
*/
void nrf_802154_core_deinit(void);
/**
* @brief Get current state of nRF 802.15.4 driver.
* @brief Gets the current state of the nRF 802.15.4 driver.
*
* @return Current state of the 802.15.4 driver.
* @returns Current state of the 802.15.4 driver.
*/
radio_state_t nrf_802154_core_state_get(void);
@@ -98,31 +98,25 @@ radio_state_t nrf_802154_core_state_get(void);
**************************************************************************************************/
/**
* @brief Request transition to SLEEP state.
*
* @note This function shall be called from a critical section context. It shall not be interrupted
* by the RADIO event handler or Radio Shceduler notification.
* @brief Requests the transition to the @ref RADIO_STATE_SLEEP state.
*
* @param[in] term_lvl Termination level of this request. Selects procedures to abort.
*
* @retval true Entering SLEEP state succeeded.
* @retval false Entering SLEEP state failed (driver is performing other procedure).
* @retval true Entering the sleep state succeeded.
* @retval false Entering the sleep state failed (the driver is performing other procedure).
*/
bool nrf_802154_core_sleep(nrf_802154_term_t term_lvl);
/**
* @brief Request transition to RECEIVE state.
*
* @note This function shall be called from a critical section context. It shall not be interrupted
* by the RADIO event handler or Radio Scheduler notification.
* @brief Requests the transition to the @ref RADIO_STATE_RX state.
*
* @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 status of this procedure. May be NULL.
* @param[in] notify_abort If abort notification should be triggered.
* @param[in] notify_function Function called to notify the status of this procedure. May be NULL.
* @param[in] notify_abort If abort notification is to be triggered.
*
* @retval true Entering RECEIVE state succeeded.
* @retval false Entering RECEIVE state failed (driver is performing other procedure).
* @retval true Entering the receive state succeeded.
* @retval false Entering the receive state failed (the driver is performing other procedure).
*/
bool nrf_802154_core_receive(nrf_802154_term_t term_lvl,
req_originator_t req_orig,
@@ -130,22 +124,19 @@ bool nrf_802154_core_receive(nrf_802154_term_t term_lvl,
bool notify_abort);
/**
* @brief Request transition to TRANSMIT state.
*
* @note This function shall be called from a critical section context. It shall not be interrupted
* by the RADIO event handler or Radio Scheduler notification.
* @brief Requests the transition to the @ref RADIO_STATE_TX state.
*
* @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 frame to transmit.
* @param[in] cca If the driver should perform CCA procedure before transmission.
* @param[in] immediate If true, the driver schedules transmission immediately or never;
* if false transmission may be postponed until tx preconditions are
* met.
* @param[in] notify_function Function called to notify status of this procedure. May be NULL.
* @param[in] cca If the driver is to perform CCA procedure before transmission.
* @param[in] immediate If true, the driver schedules transmission immediately or never.
* If false, the transmission may be postponed until
* the TX preconditions are met.
* @param[in] notify_function Function called to notify the status of this procedure. May be NULL.
*
* @retval true Entering TRANSMIT state succeeded.
* @retval false Entering TRANSMIT state failed (driver is performing other procedure).
* @retval true Entering the transmit state succeeded.
* @retval false Entering the transmit state failed (the driver is performing other procedure).
*/
bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl,
req_originator_t req_orig,
@@ -155,45 +146,40 @@ bool nrf_802154_core_transmit(nrf_802154_term_t term_lvl,
nrf_802154_notification_func_t notify_function);
/**
* @brief Request transition to ENERGY_DETECTION state.
* @brief Requests the transition to the @ref RADIO_STATE_ED state.
*
* @note This function shall be called from a critical section context. It shall not be interrupted
* by the RADIO event handler or Radio Scheduler notification.
*
* @note This function shall be called when the driver is in SLEEP or RECEIVE state. When Energy
* detection procedure is finished the driver will transit to RECEIVE state.
* When the energy detection 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.
* @param[in] time_us Minimal time of energy detection procedure.
*
* @retval true Entering ENERGY_DETECTION state succeeded.
* @retval false Entering ENERGY_DETECTION state failed (driver is performing other procedure).
* @retval true Entering the energy detection state succeeded.
* @retval false Entering the energy detection state failed
* (the driver is performing other procedure).
*/
bool nrf_802154_core_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_us);
/**
* @brief Request transition to CCA state.
*
* @note This function shall be called from a critical section context. It shall not be interrupted
* by the RADIO event handler or Radio Scheduler notification.
* @brief Requests the transition to the @ref RADIO_STATE_CCA state.
*
* @param[in] term_lvl Termination level of this request. Selects procedures to abort.
*
* @retval true Entering CCA state succeeded.
* @retval false Entering CCA state failed (driver is performing other procedure).
* @retval true Entering the CCA state succeeded.
* @retval false Entering the CCA state failed (the driver is performing other procedure).
*/
bool nrf_802154_core_cca(nrf_802154_term_t term_lvl);
/**
* @brief Request transition to CONTINUOUS_CARRIER state.
* @brief Requests the transition to the @ref RADIO_STATE_CONTINUOUS_CARRIER state.
*
* @note This function shall be called from a critical section context. It shall not be interrupted
* by the RADIO event handler or Radio Scheduler notification.
* 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 CONTINUOUS_CARRIER state succeeded.
* @retval false Entering CONTINUOUS_CARRIER state failed (driver is performing other procedure).
* @retval true Entering the continuous carrier state succeeded.
* @retval false Entering the continuous carrier state failed
* (the driver is performing other procedure).
*/
bool nrf_802154_core_continuous_carrier(nrf_802154_term_t term_lvl);
@@ -202,34 +188,47 @@ bool nrf_802154_core_continuous_carrier(nrf_802154_term_t term_lvl);
**************************************************************************************************/
/**
* @brief Notify the Core module that higher layer freed a frame buffer.
* @brief Notifies the core module that a higher layer freed a frame buffer.
*
* When there were no free buffers available the core does not start receiver. If core receives this
* notification it changes internal state to make sure receiver is started if requested.
*
* @note This function shall be called from a critical section context. It shall not be interrupted
* by the RADIO event handler or Radio Scheduler notification.
* When there are no free buffers available, the core does not start the receiver.
* If the core receives this notification, it changes the internal state to make sure
* the receiver is started if requested.
*
* @param[in] p_data Pointer to buffer that has been freed.
*/
bool nrf_802154_core_notify_buffer_free(uint8_t * p_data);
/**
* @brief Notify the Core module that next higher layer requested change of the channel.
* @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.
*
* Core should update frequency register of the peripheral and in case it is in RECEIVE state the
* receiver should be disabled and enabled again to use new channel.
*/
bool nrf_802154_core_channel_update(void);
/**
* @brief Notify the Core module that next higher layer requested change of the CCA configuration.
* @brief Notifies the core module that the next higher layer requested the change
* of the CCA configuration.
*/
bool nrf_802154_core_cca_cfg_update(void);
/**
* @brief Notifies the core module that the next higher layer requested the RSSI measurement.
*/
bool nrf_802154_core_rssi_measure(void);
/**
* @brief Gets the last RSSI measurement.
*
* @param[out] p_rssi RSSI measurement value in dBm.
*/
bool nrf_802154_core_last_rssi_measurement_get(int8_t * p_rssi);
#if !NRF_802154_INTERNAL_IRQ_HANDLING
/**
* @brief Notify the Core module that there is a pending IRQ that should be handled.
* @brief Notifies the core module that there is a pending IRQ to be handled.
*/
void nrf_802154_core_irq_handler(void);
#endif // !NRF_802154_INTERNAL_IRQ_HANDLING
@@ -51,7 +51,7 @@ typedef bool (* abort_hook)(nrf_802154_term_t term_lvl, req_originator_t req_ori
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);
typedef void (* rx_started_hook)(void);
typedef void (* rx_started_hook)(const uint8_t * p_frame);
typedef void (* rx_ack_started_hook)(void);
/* Since some compilers do not allow empty initializers for arrays with unspecified bounds,
@@ -208,7 +208,7 @@ bool nrf_802154_core_hooks_tx_started(const uint8_t * p_frame)
return result;
}
void nrf_802154_core_hooks_rx_started(void)
void nrf_802154_core_hooks_rx_started(const uint8_t * p_frame)
{
for (uint32_t i = 0; i < sizeof(m_rx_started_hooks) / sizeof(m_rx_started_hooks[0]); i++)
{
@@ -217,7 +217,7 @@ void nrf_802154_core_hooks_rx_started(void)
break;
}
m_rx_started_hooks[i]();
m_rx_started_hooks[i](p_frame);
}
}
@@ -43,58 +43,64 @@
* @ingroup nrf_802154
* @brief Hooks for the 802.15.4 driver core module.
*
* Hooks are used by optional driver features to modify way in which notifications are propagated
* through the driver.
* Hooks are used by the optional driver features to modify the way in which notifications
* are propagated through the driver.
*/
/**
* @brief Process hooks for the terminate request.
* @brief Processes hooks for the termination request.
*
* @param[in] term_lvl Termination level of request that terminates current operation.
* @param[in] term_lvl Termination level of the request that terminates the current operation.
* @param[in] req_orig Module that originates this request.
*
* @retval true All procedures are aborted.
* @retval false There is ongoing procedure that cannot be aborted due to too low @p priority.
* @retval false There is an ongoing procedure that cannot be aborted due to a too low @p term_lvl.
*/
bool nrf_802154_core_hooks_terminate(nrf_802154_term_t term_lvl, req_originator_t req_orig);
/**
* @brief Process hooks for the transmitted event.
* @brief Processes hooks for the transmitted event.
*
* @param[in] p_frame Pointer to a buffer containing PHR and PSDU of the frame that was transmitted.
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame
* that was transmitted.
*/
void nrf_802154_core_hooks_transmitted(const uint8_t * p_frame);
/**
* @brief Process hooks for the TX failed event.
* @brief Processes hooks for the TX failed event.
*
* @param[in] p_frame Pointer to a buffer containing PHR and PSDU of the frame that was not transmitted.
* @param[in] error Cause of failed transmission.
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame
* that was not transmitted.
* @param[in] error Cause of the failed transmission.
*
* @retval true TX failed event should be propagated to the MAC layer.
* @retval false TX failed event should not be propagated to the MAC layer. It is handled
* @retval true TX failed event is to be propagated to the MAC layer.
* @retval false TX failed event is not to be propagated to the MAC layer. It is handled
* internally.
*/
bool nrf_802154_core_hooks_tx_failed(const uint8_t * p_frame, nrf_802154_tx_error_t error);
/**
* @brief Process hooks for the TX started event.
* @brief Processes hooks for the TX started event.
*
* @param[in] p_frame Pointer to a buffer containing PHR and PSDU of the frame that is being transmitted.
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame
* that is being transmitted.
*
* @retval true TX started event should be propagated to the MAC layer.
* @retval false TX started event should not be propagated to the MAC layer. It is handled
* @retval true TX started event is to be propagated to the MAC layer.
* @retval false TX started event is not to be propagated to the MAC layer. It is handled
* internally.
*/
bool nrf_802154_core_hooks_tx_started(const uint8_t * p_frame);
/**
* @brief Process hooks for the RX started event.
* @brief Processes hooks for the RX started event.
*
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame
* that is being received.
*/
void nrf_802154_core_hooks_rx_started(void);
void nrf_802154_core_hooks_rx_started(const uint8_t * p_frame);
/**
* @brief Process hooks for the RX ACK started event.
* @brief Processes hooks for the RX ACK started event.
*/
void nrf_802154_core_hooks_rx_ack_started(void);
@@ -46,51 +46,49 @@ extern "C" {
*/
/**
* @brief Initialize critical section module.
* @brief Initializes the critical section module.
*/
void nrf_802154_critical_section_init(void);
/**
* @brief Enter critical section in the 802.15.4 driver.
* @brief Function for entering a critical section in the 802.15.4 driver.
*
* @note Entering critical section may be prohibited at given time. If critical section is not
* entered, request should not be proceeded.
*
* @retval true Entered critical section.
* @retval false Could not enter critical section.
* @retval true The critical section is entered.
* @retval false The critical section could not be entered.
*/
bool nrf_802154_critical_section_enter(void);
/**
* @brief Exit critical section in the 802.15.4 driver.
* @brief Function for exiting a critical section in the 802.15.4 driver.
*/
void nrf_802154_critical_section_exit(void);
/**
* @brief Forcefully enter critical section in the 802.15.4 driver.
* @brief Function for forcefully entering a critical section in the 802.15.4 driver.
*
* This function enters critical section regardless critical sections is already entered.
* With this function, the critical section is entered regardless of whether
* it has been already entered before.
*
* This function is intended to be used by RADIO IRQ handler and RAAL notifications handlers to
* This function is intended to be used by RADIO IRQ handler and RSCH notifications handlers to
* prevent interrupting of these procedures by FSM requests from higher priority IRQ handlers.
*/
void nrf_802154_critical_section_forcefully_enter(void);
/**
* @brief Allow entering nested critical section.
* @brief Allows entry to a nested critical section.
*
* This function is intended to be used with notification module in order to allow processing
* requests called from notification context.
* This function is intended to be used with the notification module to allow processing
* requests called from the notification context.
*/
void nrf_802154_critical_section_nesting_allow(void);
/**
* @brief Disallow entering nested critical section.
* @brief Denies entry to a nested critical section.
*/
void nrf_802154_critical_section_nesting_deny(void);
/**
* @brief Check if critical section is nested.
* @brief Checks if the critical section is nested.
*
* @retval true Critical section is nested.
* @retval false Critical section is not nested.
@@ -98,24 +96,24 @@ void nrf_802154_critical_section_nesting_deny(void);
bool nrf_802154_critical_section_is_nested(void);
/**
* @brief Get current IRQ priority.
* @brief Gets the current IRQ priority.
*
* @return IRQ priority
* @returns IRQ priority
*/
uint32_t nrf_802154_critical_section_active_vector_priority_get(void);
/**
* @brief Function called to enter critical section in the RSCH module.
* @brief Function for entering a critical section in the RSCH module.
*/
extern void nrf_802154_critical_section_rsch_enter(void);
/**
* @brief Function called to exit critical section in the RSCH module.
* @brief Function for exiting a critical section in the RSCH module.
*/
extern void nrf_802154_critical_section_rsch_exit(void);
/**
* @brief Check if there is pending event in the RSCH critical section.
* @brief Checks if there is a pending event in the RSCH critical section.
*/
extern bool nrf_802154_critical_section_rsch_event_is_pending(void);
@@ -183,7 +183,9 @@ void __assert_func(const char * file, int line, const char * func, const char *
(void)func;
(void)cond;
#if defined(ENABLE_DEBUG_ASSERT_BKPT) && (ENABLE_DEBUG_ASSERT_BKPT != 0)
__BKPT(0);
#endif
__disable_irq();
while (1)
@@ -196,7 +198,9 @@ void __aeabi_assert(const char * expr, const char * file, int line)
(void)file;
(void)line;
#if defined(ENABLE_DEBUG_ASSERT_BKPT) && (ENABLE_DEBUG_ASSERT_BKPT != 0)
__BKPT(0);
#endif
__disable_irq();
while (1)
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contains debug helpers for 802.15.4 radio driver for nRF SoC devices.
* @brief Module that contains debug helpers for the 802.15.4 radio driver for the nRF SoC devices.
*
*/
@@ -57,6 +57,8 @@ extern "C" {
#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
@@ -88,6 +90,7 @@ extern "C" {
#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
@@ -118,22 +121,25 @@ extern "C" {
#define FUNCTION_requested_prio_lvl_is_at_least 0x1007UL
#define FUNCTION_notify_core 0x1008UL
#define PIN_DBG_RADIO_EVT_END 11
#define PIN_DBG_RADIO_EVT_DISABLED 12
#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
#ifdef NRF52811_XXAA
#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_RADIO_EVT_END 13
#define PIN_DBG_RADIO_EVT_DISABLED 14
#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
#define PIN_DBG_RTC0_EVT_REM 31
#else
#define PIN_DBG_RADIO_EVT_END 11
#define PIN_DBG_RADIO_EVT_DISABLED 12
#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
#ifdef __cplusplus
}
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contains debug helpers for 802.15.4 radio driver for nRF SoC devices.
* @brief Module that contains debug helpers for the 802.15.4 radio driver for the nRF SoC devices.
*
*/
@@ -47,13 +47,6 @@ extern "C" {
#define EVENT_TRACE_ENTER 0x0001UL
#define EVENT_TRACE_EXIT 0x0002UL
#define PIN_DBG_RADIO_EVT_END 11
#define PIN_DBG_RADIO_EVT_DISABLED 12
#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
#define PIN_DBG_TIMESLOT_ACTIVE 3
#define PIN_DBG_TIMESLOT_EXTEND_REQ 4
#define PIN_DBG_TIMESLOT_SESSION_IDLE 16
@@ -140,7 +133,7 @@ extern volatile uint32_t nrf_802154_debug_log_ptr;
#endif // ENABLE_DEBUG_GPIO
/**
* @brief Initialize debug helpers for nRF 802.15.4 driver.
* @brief Initializes debug helpers for the nRF 802.15.4 driver.
*/
void nrf_802154_debug_init(void);
@@ -44,48 +44,48 @@ extern "C" {
* @defgroup nrf_802154_notification 802.15.4 driver notification
* @{
* @ingroup nrf_802154
* @brief Notifications to the next higher layer triggered from 802.15.4 radio driver.
* @brief Notifications to the next higher layer triggered from the 802.15.4 radio driver.
*/
/**
* @brief Function type used for external notification
* @brief Function type used for notifications from critical sections in the core module.
*
* This function is called instead of default notification. Function is passed to request to notify
* atomically during request processing.
* This function is called instead of the default notification. The function is passed to request
* notifications from a critical section during the request processing.
*
* @param[in] result If called request succeeded.
* @param[in] result If the called request succeeded.
*/
typedef void (* nrf_802154_notification_func_t)(bool result);
/**
* @brief Initialize notification module.
* @brief Initializes the notification module.
*/
void nrf_802154_notification_init(void);
/**
* @brief Notify next higher layer that a frame was received.
* @brief Notifies the next higher layer that a frame was received.
*
* @param[in] p_data Pointer to a buffer containing PHR and PSDU of the received frame.
* @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 indicating measured link quality during the frame reception.
*/
void nrf_802154_notify_received(uint8_t * p_data, int8_t power, uint8_t lqi);
/**
* @brief Notify next higher layer that reception of a frame failed.
* @brief Notifies the next higher layer that the reception of a frame failed.
*
* @param[in] error An error code that indicates reason of the failure.
* @param[in] error Error code that indicates the reason of the failure.
*/
void nrf_802154_notify_receive_failed(nrf_802154_rx_error_t error);
/**
* @brief Notify next higher layer that a frame was transmitted.
* @brief Notifies the next higher layer that a frame was transmitted.
*
* @param[in] p_frame Pointer to a buffer containing PHR and PSDU of the transmitted frame.
* @param[in] p_ack Pointer to a buffer containing PHR and PSDU of ACK frame. NULL if ACK was
* @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 containsthat contains PHR and PSDU of ACK frame. NULL if ACK was
* not requested.
* @param[in] power RSSI of received frame or 0 if ACK was not requested.
* @param[in] lqi LQI of received frame of 0 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 of 0 if ACK was not requested.
*/
void nrf_802154_notify_transmitted(const uint8_t * p_frame,
uint8_t * p_ack,
@@ -93,39 +93,39 @@ void nrf_802154_notify_transmitted(const uint8_t * p_frame,
uint8_t lqi);
/**
* @brief Notify next higher layer that a frame was not transmitted.
* @brief Notifies the next higher layer that a frame was not transmitted.
*
* @param[in] p_frame Pointer to a buffer containing PHR and PSDU of the frame that failed transmit
* operation.
* @param[in] error An error code indicating reason of the failure.
* @param[in] p_frame Pointer to a buffer that contains PHR and PSDU of the frame that failed
* the transmission operation.
* @param[in] error An error code indicating the reason of the failure.
*/
void nrf_802154_notify_transmit_failed(const uint8_t * p_frame, nrf_802154_tx_error_t error);
/**
* @brief Notify next higher layer that energy detection procedure ended.
* @brief Notifies the next higher layer that the energy detection procedure ended.
*
* @param[in] result Detected energy level.
*/
void nrf_802154_notify_energy_detected(uint8_t result);
/**
* @brief Notify next higher layer that energy detection procedure failed.
* @brief Notifies the next higher layer that the energy detection procedure failed.
*
* @param[in] error An error code indicating reason of the failure.
* @param[in] error Error code indicating the reason of the failure.
*/
void nrf_802154_notify_energy_detection_failed(nrf_802154_ed_error_t error);
/**
* @brief Notify next higher layer that CCA procedure ended.
* @brief Notifies the next higher layer that the CCA procedure ended.
*
* @param[in] is_free If detected that channel is free.
*/
void nrf_802154_notify_cca(bool is_free);
/**
* @brief Notify next higher layer that CCA procedure failed.
* @brief Notifies the next higher layer that the CCA procedure failed.
*
* @param[in] error An error code indicating reason of the failure.
* @param[in] error Error code indicating reason of the failure.
*/
void nrf_802154_notify_cca_failed(nrf_802154_cca_error_t error);
@@ -29,7 +29,7 @@
*/
/**
* @brief This file implements storage of PIB attributes in nRF 802.15.4 radio driver.
* @brief Module that implements the storage of PIB attributes in the nRF 802.15.4 radio driver.
*
*/
@@ -46,142 +46,143 @@ extern "C" {
#endif
/**
* @brief Initialize this module.
* @brief Initializes this module.
*/
void nrf_802154_pib_init(void);
/**
* @brief Check if promiscuous mode is enabled.
* @brief Checks if the promiscuous mode is enabled.
*
* @retval true If promiscuous mode is enabled.
* @retval false If promiscuous mode is disabled.
* @retval true The promiscuous mode is enabled.
* @retval false The promiscuous mode is disabled.
*/
bool nrf_802154_pib_promiscuous_get(void);
/**
* @brief Enable or disable promiscuous mode.
* @brief Enables or disables the promiscuous mode.
*
* @param[in] enabled If promiscuous mode should be enabled.
* @param[in] enabled If the promiscuous mode is to be enabled.
*/
void nrf_802154_pib_promiscuous_set(bool enabled);
/**
* @brief Check if auto ACK procedure is enabled.
* @brief Checks if the auto ACK procedure is enabled.
*
* @retval true If auto ACK procedure is enabled.
* @retval false If auto ACK procedure is disabled.
* @retval true The auto ACK procedure is enabled.
* @retval false The auto ACK procedure is disabled.
*/
bool nrf_802154_pib_auto_ack_get(void);
/**
* @brief Enable or disable auto ACK procedure.
* @brief Enables or disables the auto ACK procedure.
*
* @param[in] enabled If auto ACK procedure should be enabled.
* @param[in] enabled If the auto ACK procedure is to be enabled.
*/
void nrf_802154_pib_auto_ack_set(bool enabled);
/**
* @brief Check if radio is configured as the PAN coordinator.
* @brief Checks if the radio is configured as the PAN coordinator.
*
* @retval true If radio is configured as the PAN coordinator.
* @retval false If radio is not configured as the PAN coordinator.
* @retval true The radio is configured as the PAN coordinator.
* @retval false The radio is not configured as the PAN coordinator.
*/
bool nrf_802154_pib_pan_coord_get(void);
/**
* @brief Notify driver that radio is configured as the PAN coordinator.
* @brief Configures the device as the PAN coordinator.
*
* @param[in] enabled If radio is configured as the PAN coordinator.
* @param[in] enabled If the radio is configured as the PAN coordinator.
*/
void nrf_802154_pib_pan_coord_set(bool enabled);
/**
* @brief Get currently used channel.
* @brief Gets the currently used channel.
*
* @return Channel number used by the driver.
* @returns Channel number used by the driver.
*/
uint8_t nrf_802154_pib_channel_get(void);
/**
* @brief Set channel that will be used by the driver.
* @brief Sets the channel that will be used by the driver.
*
* @param[in] channel Number of channel used by the driver.
* @param[in] channel Number of the channel used by the driver.
*/
void nrf_802154_pib_channel_set(uint8_t channel);
/**
* @brief Get transmit power.
* @brief Gets the transmit power.
*
* @returns Transmit power [dBm].
* @returns Transmit power in dBm.
*/
nrf_radio_txpower_t nrf_802154_pib_tx_power_get(void);
/**
* @brief Set transmit power used for ACK frames.
* @brief Sets the transmit power used for ACK frames.
*
* @param[in] dbm Transmit power [dBm].
* @param[in] dbm Transmit power in dBm.
*/
void nrf_802154_pib_tx_power_set(int8_t dbm);
/**
* @brief Get PAN Id used by this device.
* @brief Gets the PAN ID used by this device.
*
* @returns Pointer to buffer containing PAN Id value (2 bytes, little-endian).
* @returns Pointer to the buffer containing the PAN ID value (2 bytes, little-endian).
*/
const uint8_t * nrf_802154_pib_pan_id_get(void);
/**
* @brief Set PAN Id used by this device.
* @brief Sets the PAN ID used by this device.
*
* @param[in] p_pan_id Pointer to PAN Id (2 bytes, little-endian).
* @param[in] p_pan_id Pointer to the PAN ID (2 bytes, little-endian).
*
* This function makes copy of the PAN Id.
* This function makes a copy of the PAN ID.
*/
void nrf_802154_pib_pan_id_set(const uint8_t * p_pan_id);
/**
* @brief Get Extended Address of this device
* @brief Gets the extended address of this device.
*
* @returns Pointer to buffer containing extended address (8 bytes, little-endian).
* @returns Pointer to the buffer containing the extended address (8 bytes, little-endian).
*/
const uint8_t * nrf_802154_pib_extended_address_get(void);
/**
* @brief Set Extended Address of this device.
* @brief Sets the extended address of this device.
*
* @param[in] p_extended_address Pointer to extended address (8 bytes, little-endian).
*
* This function makes copy of the address.
* This function makes a copy of the address.
*/
void nrf_802154_pib_extended_address_set(const uint8_t * p_extended_address);
/**
* @brief Get Short Address of this device
* @brief Gets the short address of this device.
*
* @returns Pointer to buffer containing short address (2 bytes, little-endian).
* @returns Pointer to the buffer containing the short address (2 bytes, little-endian).
*/
const uint8_t * nrf_802154_pib_short_address_get(void);
/**
* @brief Set Short Address of this device.
* @brief Sets the short address of this device.
*
* @param[in] p_short_address Pointer to short address (2 bytes, little-endian).
* @param[in] p_short_address Pointer to the short address (2 bytes, little-endian).
*
* This function makes copy of the address.
* This function makes a copy of the address.
*/
void nrf_802154_pib_short_address_set(const uint8_t * p_short_address);
/**
* @brief Set radio CCA mode and threshold.
* @brief Sets the radio CCA mode and threshold.
*
* @param[in] p_cca_cfg A pointer to the CCA configuration structure. Only fields relevant to selected mode are updated.
* @param[in] p_cca_cfg Pointer to the CCA configuration structure. Only fields relevant
* to the selected mode are updated.
*/
void nrf_802154_pib_cca_cfg_set(const nrf_802154_cca_cfg_t * p_cca_cfg);
/**
* @brief Get current radio CCA configuration.
* @brief Gets the current radio CCA configuration.
*
* @param[out] p_cca_cfg A pointer to the structure for current CCA configuration.
* @param[out] p_cca_cfg Pointer to the structure for the current CCA configuration.
*/
void nrf_802154_pib_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg);
@@ -36,30 +36,30 @@ extern "C" {
#endif
/**
* @defgroup nrf_802154_priority_drop 802.15.4 driver procedures with lower priority.
* @defgroup nrf_802154_priority_drop 802.15.4 driver procedures with lower priority
* @{
* @ingroup nrf_802154
* @brief Internal procedures of 802.15.4 driver that should be called with lower priority than
* @brief Internal procedures of the 802.15.4 driver that should be called with lower priority than
* the caller's priority.
*/
/**
* @brief Initialize notification module.
* @brief Initializes the notification module.
*/
void nrf_802154_priority_drop_init(void);
/**
* @brief Request stop of the high frequency clock.
* @brief Requests the stop of the high frequency clock.
*
* @note This function should be called through this module to prevent calling it from the arbiter
* @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 Terminate requesting of high frequency clock stop.
* @brief Terminates the requesting of the high frequency clock stop procedure.
*
* Function used to to terminate HFClk stop procedure requested by previous call to
* 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.
*/
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contains calculations of 802.15.4 radio driver procedures duration.
* @brief Module that contains calculations of the duration of the 802.15.4 radio driver procedures.
*
*/
@@ -1,4 +1,4 @@
/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -50,30 +50,30 @@ extern "C" {
*/
/**
* @brief Initialize request module.
* @brief Initializes the request module.
*/
void nrf_802154_request_init(void);
/**
* @brief Request entering sleep state.
* @brief Requests entering the @ref RADIO_STATE_SLEEP state for the driver.
*
* @param[in] term_lvl Termination level of this request. Selects procedures to abort.
*
* @retval true The driver will enter sleep state.
* @retval false The driver cannot enter sleep state due to ongoing operation.
* @retval false The driver cannot enter the sleep state due to an ongoing operation.
*/
bool nrf_802154_request_sleep(nrf_802154_term_t term_lvl);
/**
* @brief Request entering receive state.
* @brief Requests entering the @ref RADIO_STATE_RX state for the driver.
*
* @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 status of this procedure. May be NULL.
* @param[in] notify_abort If abort notification should be triggered automatically.
* @param[in] notify_function Function called to notify the status of this procedure. May be NULL.
* @param[in] notify_abort If the abort notification is to be triggered automatically.
*
* @retval true The driver will enter receive state.
* @retval false The driver cannot enter receive state due to ongoing operation.
* @retval true The driver will enter the receive state.
* @retval false The driver cannot enter the receive state due to ongoing operation.
*/
bool nrf_802154_request_receive(nrf_802154_term_t term_lvl,
req_originator_t req_orig,
@@ -81,19 +81,19 @@ bool nrf_802154_request_receive(nrf_802154_term_t term_lvl,
bool notify_abort);
/**
* @brief Request entering transmit state.
* @brief Request entering the @ref RADIO_STATE_TX state for the driver.
*
* @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 the frame to transmit.
* @param[in] cca If the driver should perform CCA procedure before transmission.
* @param[in] immediate If true, the driver schedules transmission immediately or never;
* if false transmission may be postponed until tx preconditions are
* met.
* @param[in] notify_function Function called to notify status of this procedure. May be NULL.
* @param[in] cca If the driver is to perform the CCA procedure before transmission.
* @param[in] immediate If true, the driver schedules transmission immediately or never.
* If false, the transmission can be postponed until the TX
* preconditions are met.
* @param[in] notify_function Function called to notify the status of this procedure. May be NULL.
*
* @retval true The driver will enter transmit state.
* @retval false The driver cannot enter transmit state due to ongoing operation.
* @retval true The driver will enter the transmit state.
* @retval false The driver cannot enter the transmit state due to an ongoing operation.
*/
bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl,
req_originator_t req_orig,
@@ -103,53 +103,63 @@ bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl,
nrf_802154_notification_func_t notify_function);
/**
* @brief Request entering energy detection state.
* @brief Requests entering the @ref RADIO_STATE_ED state.
*
* @param[in] term_lvl Termination level of this request. Selects procedures to abort.
* @param[in] time_us Requested duration of energy detection procedure.
* @param[in] time_us Requested duration of the energy detection procedure.
*
* @retval true The driver will enter energy detection state.
* @retval false The driver cannot enter energy detection state due to ongoing operation.
* @retval false The driver cannot enter the energy detection state due to an ongoing operation.
*/
bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_us);
/**
* @brief Request entering CCA state.
* @brief Requests entering the @ref RADIO_STATE_CCA state.
*
* @param[in] term_lvl Termination level of this request. Selects procedures to abort.
*
* @retval true The driver will enter CCA state.
* @retval false The driver cannot enter CCA state due to ongoing operation.
* @retval true The driver will enter the CCA state.
* @retval false The driver cannot enter the CCA state due to an ongoing operation.
*/
bool nrf_802154_request_cca(nrf_802154_term_t term_lvl);
/**
* @brief Request entering continuous carrier state.
* @brief Requests entering the @ref RADIO_STATE_CONTINUOUS_CARRIER state.
*
* @param[in] term_lvl Termination level of this request. Selects procedures to abort.
*
* @retval true The driver will enter continuous carrier state.
* @retval false The driver cannot enter continuous carrier state due to ongoing operation.
* @retval true The driver will enter the continuous carrier state.
* @retval false The driver cannot enter the continuous carrier state due to an ongoing operation.
*/
bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl);
/**
* @brief Request the driver to free given buffer.
* @brief Requests the driver to free the given buffer.
*
* @param[in] p_data Pointer to the buffer to free.
* @param[in] p_data Pointer to the buffer to be freed.
*/
bool nrf_802154_request_buffer_free(uint8_t * p_data);
/**
* @brief Request the driver to update channel number used by the RADIO peripheral.
* @brief Requests the driver to update the channel number used by the RADIO peripheral.
*/
bool nrf_802154_request_channel_update(void);
/**
* @brief Request the driver to update CCA configuration used by the RADIO peripheral.
* @brief Requests the driver to update the CCA configuration used by the RADIO peripheral.
*/
bool nrf_802154_request_cca_cfg_update(void);
/**
* @brief Requests the RSSI measurement.
*/
bool nrf_802154_request_rssi_measure(void);
/**
* @brief Requests getting the last RSSI measurement result.
*/
bool nrf_802154_request_rssi_measurement_get(int8_t * p_rssi);
/**
*@}
**/
@@ -1,4 +1,4 @@
/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -112,3 +112,13 @@ bool nrf_802154_request_cca_cfg_update(void)
{
REQUEST_FUNCTION(nrf_802154_core_cca_cfg_update)
}
bool nrf_802154_request_rssi_measure(void)
{
REQUEST_FUNCTION(nrf_802154_core_rssi_measure)
}
bool nrf_802154_request_rssi_measurement_get(int8_t * p_rssi)
{
REQUEST_FUNCTION(nrf_802154_core_last_rssi_measurement_get, p_rssi)
}
@@ -1,4 +1,4 @@
/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
/* Copyright (c) 2017 - 2019, Nordic Semiconductor ASA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -172,3 +172,15 @@ bool nrf_802154_request_cca_cfg_update(void)
{
REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_cca_cfg_update, nrf_802154_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)
}
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,
p_rssi)
}
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contains helpers for checking nRF SoC revision.
* @brief Module that contains helpers for checking the nRF SoC revision.
*
*/
@@ -44,19 +44,20 @@ extern "C" {
#endif
/**
* @brief This function initializes the module by reading the nRF52840 revision
* from the registers and storing it for convenient access.
* @brief Initializes the module by reading the nRF52840 revision from the registers and storing it
* for convenient access.
*
* @note If the chip revision is not recognized, this module assumes that it is running on a newer
* chip revision that has all of the features, that the most recent known revision has.
* chip revision that has all of the features compared to the features of the most recent
* known revision.
*/
void nrf_802154_revision_init(void);
/**
* @brief Function to check if the program is running on NRF52840 revision that supports PHYEND event.
* @brief Checks if the program is running on the nRF52840 revision that supports the PHYEND event.
*
* @retval true If PHYEND event is supported.
* @retval false If PHYEND event is not supported.
* @retval true The PHYEND event is supported.
* @retval false The PHYEND event is not supported.
*/
bool nrf_802154_revision_has_phyend_event(void);
@@ -34,50 +34,52 @@
#include <stdint.h>
/**
* @defgroup nrf_802154_rssi RSSI calculations used internally in the 802.15.4 driver.
* @defgroup nrf_802154_rssi RSSI calculations used internally in the 802.15.4 driver
* @{
* @ingroup nrf_802154
* @brief RSSI calculations used internally in the 802.15.4 driver.
*/
/**
* @brief Get RSSISAMPLE temperature correction value for temperature provided by platform.
* @brief Gets the RSSISAMPLE temperature correction value.
*
* The correction value is based on the last temperature value reported by the platform.
*
* @returns RSSISAMPLE temperature correction value (Errata 153).
*/
int8_t nrf_802154_rssi_sample_temp_corr_value_get(void);
/**
* @brief Adjust the given RSSISAMPLE value using a temperature correction factor.
* @brief Adjusts the given RSSISAMPLE value by a temperature correction factor.
*
* @param[in] rssi_sample Value read from RSSISAMPLE register.
* @param[in] rssi_sample Value read from the RSSISAMPLE register.
*
* @returns RSSISAMPLE corrected by a temperature factor (Errata 153).
*/
uint8_t nrf_802154_rssi_sample_corrected_get(uint8_t rssi_sample);
/**
* @brief Adjust the reported LQI value using a temperature correction factor.
* @brief Adjusts the reported LQI value using a temperature correction factor.
*
* @param[in] lqi Value read from LQI byte.
* @param[in] lqi Value read from the LQI byte.
*
* @returns LQI byte value corrected by a temperature factor (Errata 153).
*/
uint8_t nrf_802154_rssi_lqi_corrected_get(uint8_t lqi);
/**
* @brief Adjust the EDSAMPLE value using a temperature correction factor.
* @brief Adjusts the EDSAMPLE value using a temperature correction factor.
*
* @param[in] ed Value read from EDSAMPLE register.
* @param[in] ed Value read from the EDSAMPLE register.
*
* @returns EDSAMPLE value corrected by a temperature factor (Errata 153).
*/
uint8_t nrf_802154_rssi_ed_corrected_get(uint8_t ed);
/**
* @brief Adjust the CCA ED threshold value using a temperature correction factor.
* @brief Adjusts the CCA ED threshold value using a temperature correction factor.
*
* @param[in] cca_ed Value representing CCA ED threshold that should be corrected.
* @param[in] cca_ed Value representing the CCA ED threshold to be corrected.
*
* @returns CCA ED threshold value corrected by a temperature factor (Errata 153).
*/
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contains buffer for frames received by nRF 802.15.4 radio driver.
* @brief Module that contains buffer for frames received by the nRF 802.15.4 radio driver.
*
*/
@@ -46,7 +46,7 @@ extern "C" {
#endif
/**
* @brief Structure containing received frame.
* @brief Structure that contains the received frame.
*/
typedef struct
{
@@ -55,23 +55,23 @@ typedef struct
} rx_buffer_t;
/**
* @brief Array containing all buffers used to receive frame.
* @brief Array that contains all buffers used to receive frame.
*
* This array is in global scope to allow optimizations in Core module in case there is only
* This array is in the global scope to allow optimizations in the core module if there is only
* one buffer provided by this module.
*
*/
extern rx_buffer_t nrf_802154_rx_buffers[];
/**
* @brief Initialize buffer for received frames.
* @brief Initializes the buffer for received frames.
*/
void nrf_802154_rx_buffer_init(void);
/**
* @brief Get free buffer to receive a frame.
* @brief Gets a free buffer to receive a frame.
*
* @return Pointer to free buffer of NULL if no free buffer is available.
* @returns Pointer to a free buffer, or NULL if no free buffer is available.
*/
rx_buffer_t * nrf_802154_rx_buffer_free_find(void);
@@ -44,6 +44,7 @@
#include "nrf_802154_config.h"
#include "nrf_802154_core.h"
#include "nrf_802154_rx_buffer.h"
#include "nrf_802154_utils.h"
#include "nrf_egu.h"
#include "platform/clock/nrf_802154_clock.h"
@@ -157,7 +158,9 @@ typedef enum
REQ_TYPE_CONTINUOUS_CARRIER,
REQ_TYPE_BUFFER_FREE,
REQ_TYPE_CHANNEL_UPDATE,
REQ_TYPE_CCA_CFG_UPDATE
REQ_TYPE_CCA_CFG_UPDATE,
REQ_TYPE_RSSI_MEASURE,
REQ_TYPE_RSSI_GET,
} nrf_802154_req_type_t;
/// Request data in request queue.
@@ -225,9 +228,20 @@ typedef struct
struct
{
bool * p_result; ///< CCA config update request result.
} cca_cfg_update; ///< CCA config update request details.
} data; ///< Request data depending on it's type.
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.
@@ -434,6 +448,9 @@ void nrf_802154_swi_init(void)
nrf_egu_int_enable(SWI_EGU, NTF_INT | HFCLK_STOP_INT | REQ_INT);
#if !NRF_IS_IRQ_PRIORITY_ALLOWED(NRF_802154_SWI_PRIORITY)
#error NRF_802154_SWI_PRIORITY value out of the allowed range.
#endif
NVIC_SetPriority(SWI_IRQn, NRF_802154_SWI_PRIORITY);
NVIC_ClearPendingIRQ(SWI_IRQn);
NVIC_EnableIRQ(SWI_IRQn);
@@ -658,6 +675,27 @@ void nrf_802154_swi_cca_cfg_update(bool * p_result)
req_exit();
}
void nrf_802154_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();
}
void nrf_802154_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 SWI_IRQHandler(void)
{
if (nrf_egu_event_check(SWI_EGU, NTF_EVENT))
@@ -809,6 +847,15 @@ void SWI_IRQHandler(void)
*(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);
}
@@ -46,38 +46,42 @@ extern "C" {
* @defgroup nrf_802154_swi 802.15.4 driver SWI management
* @{
* @ingroup nrf_802154
* @brief SWI manager for 802.15.4 driver.
* @brief SWI manager for the 802.15.4 driver.
*/
/**
* @brief Initialize SWI module.
* @brief Initializes the SWI module.
*/
void nrf_802154_swi_init(void);
/**
* @brief Notify next higher layer that a frame was received from SWI priority level.
* @brief Notifies the next higher layer that a frame was received.
*
* @param[in] p_data Pointer to a buffer containing PHR and PSDU of the received frame.
* 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 indicating measured link quality 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 Notify next higher layer that reception of a frame failed.
* @brief Notifies the next higher layer that the reception of a frame failed.
*
* @param[in] error An error code that indicates reason of the failure.
* @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 Notify next higher layer that a frame was transmitted from SWI priority level.
* @brief Notifies the next higher layer that a frame was transmitted
*
* @param[in] p_frame Pointer to a buffer containing PHR and PSDU of the transmitted frame.
* @param[in] p_ack Pointer to a buffer containing PHR and PSDU of ACK frame. NULL if ACK was
* 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 received frame or 0 if ACK was not requested.
* @param[in] lqi LQI of received frame of 0 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,
@@ -85,73 +89,83 @@ void nrf_802154_swi_notify_transmitted(const uint8_t * p_frame,
uint8_t lqi);
/**
* @brief Notify next higher layer that a frame was not transmitted from SWI priority level.
* @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 containing PHR and PSDU of the frame that failed
* @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 Notify next higher layer that energy detection procedure ended from SWI priority level.
* @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 Notify next higher layer that energy detection procedure failed from SWI priority level.
* @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 Notify next higher layer that CCA procedure ended from SWI priority level.
* @brief Notifies the next higher layer that the Clear Channel Assessment (CCA) procedure ended.
*
* @param[in] channel_free If detected free channel.
* 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 Notify next higher layer that CCA procedure failed from SWI priority level.
* @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 Request stop of the HF clock from the SWI priority level.
* @brief Requests a stop of the HF clock.
*
* @note This function should be called through notification module to prevent calling it from
* 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 Terminate stopping of the HF clock.
* @brief Terminates the stopping of the HF clock.
*
* @note This function terminates stopping of the HF clock only if it has not been performed.
* @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 Request entering sleep state from SWI priority.
* @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 sleep state.
* @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 Request entering receive state from SWI priority.
* @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 status of this procedure. May be NULL.
* @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 receive state.
* @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,
@@ -160,19 +174,20 @@ void nrf_802154_swi_receive(nrf_802154_term_t term_lvl,
bool * p_result);
/**
* @biref Request entering transmit state from SWI priority.
* @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 containing PHR and PSDU of the frame to be
* @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 CCA procedure before transmission.
* @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 transmission may be postponed until tx preconditions are
* met.
* @param[in] notify_function Function called to notify status of this procedure instead of
* default notification. If NULL default notification is used.
* @param[out] p_result Result of entering transmit state.
* 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,
@@ -183,49 +198,60 @@ void nrf_802154_swi_transmit(nrf_802154_term_t term_lvl,
bool * p_result);
/**
* @brief Request entering energy detection state from SWI priority.
* @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 energy detection procedure.
* @param[out] p_result Result of entering energy detection state.
* @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 Request entering CCA state from SWI priority.
* @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 CCA state.
* @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 Request entering continuous carrier state from SWI priority.
* @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 continuous carrier state.
* @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 Notify Core module that given buffer is not used anymore and can be freed.
* @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 free.
* @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 Notify Core module that the next higher layer requested channel change.
* @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 Notify Core module that the next higher layer requested CCA configuration change.
* @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);
/**
*@}
**/
@@ -29,7 +29,7 @@
*/
/**
* @brief This module defines the Timer Coordinator interface.
* @brief Module that defines the Timer Coordinator interface.
*
*/
@@ -47,57 +47,59 @@ extern "C" {
* @defgroup nrf_802154_timer_coord Timer Coordinator
* @{
* @ingroup nrf_802154
* @brief Timer Coordinator interface.
* @brief The Timer Coordinator interface.
*
* Timer Coordinator is responsible to synchronize and coordinate operations of the Low Power timer
* that counts absolute time and the High Precision timer that counts time relative to a timeslot.
* Timer Coordinator is responsible for synchronizing and coordinating operations of the Low Power
* timer that counts the absolute time and the High Precision timer that counts the time relative to
* a timeslot.
*/
/**
* @brief Initialize the Timer Coordinator module.
* @brief Initializes the Timer Coordinator module.
*
*/
void nrf_802154_timer_coord_init(void);
/**
* @brief Uninitialize the Timer Coordinator module.
* @brief Deinitializes the Timer Coordinator module.
*
*/
void nrf_802154_timer_coord_uninit(void);
/**
* @brief Start the Timer Coordinator.
* @brief Starts the Timer Coordinator module.
*
* This function starts the HP timer and synchronizes it with the LP timer.
*
* Started Timer Coordinator resynchronizes automatically in constant interval.
* Once started, Timer Coordinator resynchronizes automatically in a constant interval.
*/
void nrf_802154_timer_coord_start(void);
/**
* @brief Stop the Timer Coordinator.
* @brief Stops the Timer Coordinator module.
*
* This function stops the HP timer.
*/
void nrf_802154_timer_coord_stop(void);
/**
* @brief Prepare getting precise timestamp of given event.
* @brief Prepares for getting a precise timestamp of the given event.
*
* @param[in] event_addr Address of the peripheral register corresponding to the event that
* should be timestamped.
* is to be time-stamped.
*/
void nrf_802154_timer_coord_timestamp_prepare(uint32_t event_addr);
/**
* @brief Get timestamp of the recently prepared event.
* @brief Gets the timestamp of the recently prepared event.
*
* If recently prepared event occurred a few times since preparation, this function returns
* timestamp of the first occurrence.
* If the requested event did not occur since preparation or HP timer is not synchronized, this
* function returns false.
* If the recently prepared event occurred a few times since the preparation, this function returns
* the timestamp of the first occurrence.
* If the requested event did not occur since the preparation or the HP timer is not synchronized,
* this function returns false.
*
* @param[out] p_timestamp Precise absolute timestamp of recently prepared event [us].
* @param[out] p_timestamp Precise absolute timestamp of the recently prepared event,
* in microseconds (us).
*
* @retval true Timestamp is available.
* @retval false Timestamp is unavailable.
@@ -36,7 +36,7 @@
#include "nrf_radio.h"
/**
* @defgroup nrf_802154_types Type definitions used in the 802.15.4 driver.
* @defgroup nrf_802154_types Type definitions used in the 802.15.4 driver
* @{
* @ingroup nrf_802154
* @brief Definitions of types used in the 802.15.4 driver.
@@ -48,57 +48,57 @@
typedef uint8_t nrf_802154_state_t;
#define NRF_802154_STATE_INVALID 0x01 // !< Radio in an invalid state.
#define NRF_802154_STATE_SLEEP 0x02 // !< Radio in sleep state.
#define NRF_802154_STATE_RECEIVE 0x03 // !< Radio in receive state.
#define NRF_802154_STATE_TRANSMIT 0x04 // !< Radio in transmit state.
#define NRF_802154_STATE_ENERGY_DETECTION 0x05 // !< Radio in energy detection state.
#define NRF_802154_STATE_CCA 0x06 // !< Radio in CCA state.
#define NRF_802154_STATE_CONTINUOUS_CARRIER 0x07 // !< Radio in continuous carrier state.
#define NRF_802154_STATE_SLEEP 0x02 // !< Radio in the sleep state.
#define NRF_802154_STATE_RECEIVE 0x03 // !< Radio in the receive state.
#define NRF_802154_STATE_TRANSMIT 0x04 // !< Radio in the transmit state.
#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.
/**
* @brief Errors reported during frame transmission.
* @brief Errors reported during the frame transmission.
*/
typedef uint8_t nrf_802154_tx_error_t;
#define NRF_802154_TX_ERROR_NONE 0x00 // !< There is no transmit error.
#define NRF_802154_TX_ERROR_BUSY_CHANNEL 0x01 // !< CCA reported busy channel prior to transmission.
#define NRF_802154_TX_ERROR_BUSY_CHANNEL 0x01 // !< CCA reported busy channel before the transmission.
#define NRF_802154_TX_ERROR_INVALID_ACK 0x02 // !< Received ACK frame is other than expected.
#define NRF_802154_TX_ERROR_NO_MEM 0x03 // !< No receive buffer is available to receive an ACK.
#define NRF_802154_TX_ERROR_TIMESLOT_ENDED 0x04 // !< Radio timeslot ended during transmission procedure.
#define NRF_802154_TX_ERROR_NO_ACK 0x05 // !< ACK frame was not received during timeout period.
#define NRF_802154_TX_ERROR_ABORTED 0x06 // !< Procedure was aborted by another driver operation with FORCE priority.
#define NRF_802154_TX_ERROR_TIMESLOT_DENIED 0x07 // !< Transmission did not start due to denied timeslot request.
#define NRF_802154_TX_ERROR_TIMESLOT_ENDED 0x04 // !< Radio timeslot ended during the transmission procedure.
#define NRF_802154_TX_ERROR_NO_ACK 0x05 // !< ACK frame was not received during the timeout period.
#define NRF_802154_TX_ERROR_ABORTED 0x06 // !< Procedure was aborted by another operation.
#define NRF_802154_TX_ERROR_TIMESLOT_DENIED 0x07 // !< Transmission did not start due to a denied timeslot request.
/**
* @brief Possible errors during frame reception.
* @brief Possible errors during the frame reception.
*/
typedef uint8_t nrf_802154_rx_error_t;
#define NRF_802154_RX_ERROR_NONE 0x00 // !< There is no receive error.
#define NRF_802154_RX_ERROR_INVALID_FRAME 0x01 // !< Received a malformed frame.
#define NRF_802154_RX_ERROR_INVALID_FCS 0x02 // !< Received a frame with invalid checksum.
#define NRF_802154_RX_ERROR_INVALID_DEST_ADDR 0x03 // !< Received a frame with mismatched destination address.
#define NRF_802154_RX_ERROR_RUNTIME 0x04 // !< A runtime error occurred (for example, CPU was held for too long).
#define NRF_802154_RX_ERROR_TIMESLOT_ENDED 0x05 // !< Radio timeslot ended during frame reception.
#define NRF_802154_RX_ERROR_ABORTED 0x06 // !< Procedure was aborted by another driver operation with FORCE priority.
#define NRF_802154_RX_ERROR_DELAYED_TIMESLOT_DENIED 0x07 // !< Delayed reception request was rejected due to denied timeslot request.
#define NRF_802154_RX_ERROR_DELAYED_TIMEOUT 0x08 // !< Frame not received during delayed reception time slot.
#define NRF_802154_RX_ERROR_INVALID_FCS 0x02 // !< Received a frame with an invalid checksum.
#define NRF_802154_RX_ERROR_INVALID_DEST_ADDR 0x03 // !< Received a frame with a mismatched destination address.
#define NRF_802154_RX_ERROR_RUNTIME 0x04 // !< Runtime error occurred (for example, CPU was held for too long).
#define NRF_802154_RX_ERROR_TIMESLOT_ENDED 0x05 // !< Radio timeslot ended during the frame reception.
#define NRF_802154_RX_ERROR_ABORTED 0x06 // !< Procedure was aborted by another operation.
#define NRF_802154_RX_ERROR_DELAYED_TIMESLOT_DENIED 0x07 // !< Delayed reception request was rejected due to a denied timeslot request.
#define NRF_802154_RX_ERROR_DELAYED_TIMEOUT 0x08 // !< Delayed reception timeslot ended.
#define NRF_802154_RX_ERROR_INVALID_LENGTH 0x09 // !< Received a frame with invalid length.
#define NRF_802154_RX_ERROR_DELAYED_ABORTED 0x0A // !< Delayed operation in ongoing state was aborted by other request.
#define NRF_802154_RX_ERROR_DELAYED_ABORTED 0x0A // !< Delayed operation in the ongoing state was aborted by other request.
/**
* @brief Possible errors during energy detection.
* @brief Possible errors during the energy detection.
*/
typedef uint8_t nrf_802154_ed_error_t;
#define NRF_802154_ED_ERROR_ABORTED 0x01 // !< Procedure was aborted by another driver operation with FORCE priority.
#define NRF_802154_ED_ERROR_ABORTED 0x01 // !< Procedure was aborted by another operation.
/**
* @brief Possible errors during CCA procedure.
* @brief Possible errors during the CCA procedure.
*/
typedef uint8_t nrf_802154_cca_error_t;
#define NRF_802154_CCA_ERROR_ABORTED 0x01 // !< Procedure was aborted by another driver operation with FORCE priority.
#define NRF_802154_CCA_ERROR_ABORTED 0x01 // !< Procedure was aborted by another operation.
/**
* @brief Possible errors during sleep procedure call.
@@ -106,7 +106,7 @@ typedef uint8_t nrf_802154_cca_error_t;
typedef uint8_t nrf_802154_sleep_error_t;
#define NRF_802154_SLEEP_ERROR_NONE 0x00 // !< There is no error.
#define NRF_802154_SLEEP_ERROR_BUSY 0x01 // !< The driver cannot enter sleep state due to ongoing operation.
#define NRF_802154_SLEEP_ERROR_BUSY 0x01 // !< The driver cannot enter the sleep state due to the ongoing operation.
/**
* @brief Termination level selected for a particular request.
@@ -117,7 +117,7 @@ typedef uint8_t nrf_802154_sleep_error_t;
typedef uint8_t nrf_802154_term_t;
#define NRF_802154_TERM_NONE 0x00 // !< Request is skipped if another operation is ongoing.
#define NRF_802154_TERM_802154 0x01 // !< Request terminates ongoing 802.15.4 operation.
#define NRF_802154_TERM_802154 0x01 // !< Request terminates the ongoing 802.15.4 operation.
/**
* @brief Structure for configuring CCA.
@@ -125,19 +125,25 @@ typedef uint8_t nrf_802154_term_t;
typedef struct
{
nrf_radio_cca_mode_t mode; // !< CCA mode.
uint8_t ed_threshold; // !< CCA energy busy threshold. Not used in NRF_RADIO_CCA_MODE_CARRIER.
uint8_t corr_threshold; // !< CCA correlator busy threshold. Not used in NRF_RADIO_CCA_MODE_ED.
uint8_t corr_limit; // !< Limit of occurrences above CCA correlator busy threshold. Not used in NRF_RADIO_CCA_MODE_ED.
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.
} nrf_802154_cca_cfg_t;
/**
* @brief Types of data that can be set in an Ack message.
* @brief Types of data that can be set in an ACK message.
*/
typedef uint8_t nrf_802154_ack_data_t;
#define NRF_802154_ACK_DATA_PENDING_BIT 0x00
#define NRF_802154_ACK_DATA_IE 0x01
/**
* @brief RSSI measurement results.
*/
#define NRF_802154_RSSI_INVALID INT8_MAX
/**
*@}
**/
@@ -36,7 +36,7 @@
#include "nrf.h"
/**
* @defgroup nrf_802154_utils Utils definitions used in the 802.15.4 driver.
* @defgroup nrf_802154_utils Utils definitions used in the 802.15.4 driver
* @{
* @ingroup nrf_802154
* @brief Definitions of utils used in the 802.15.4 driver.
@@ -45,66 +45,73 @@
/**@brief RTC clock frequency. */
#define NRF_802154_RTC_FREQUENCY 32768UL
/**@brief Defines number of microseconds in one second. */
/**@brief Defines the number of microseconds in one second. */
#define NRF_802154_US_PER_S 1000000ULL
/**@brief Number of microseconds in one RTC tick. (rounded up) */
/**@brief Number of microseconds in one RTC tick (rounded up). */
#define NRF_802154_US_PER_TICK NRF_802154_RTC_TICKS_TO_US(1)
/**@brief Number of bits to shift RTC_FREQUENCY and US_PER_S to achieve division by greatest common divisor. */
/**@brief Number of bits to shift RTC_FREQUENCY and US_PER_S to achieve the division by greatest common divisor. */
#define NRF_802154_FREQUENCY_US_PER_S_GCD_BITS 6
/**@brief Ceil division helper */
/**@brief Ceil division helper. */
#define NRF_802154_DIVIDE_AND_CEIL(A, B) (((A) + (B)-1) / (B))
/**@brief RTC ticks to us conversion. */
/**@brief Defines the conversion of RTC ticks to microseconds (us). */
#define NRF_802154_RTC_TICKS_TO_US(ticks) \
NRF_802154_DIVIDE_AND_CEIL( \
(ticks) * (NRF_802154_US_PER_S >> NRF_802154_FREQUENCY_US_PER_S_GCD_BITS), \
(NRF_802154_RTC_FREQUENCY >> NRF_802154_FREQUENCY_US_PER_S_GCD_BITS))
/**@brief Macro to get number of elements in array.
/** Checks if the given IRQ priority is within the range implemented by the MCU. */
#define NRF_IS_IRQ_PRIORITY_ALLOWED(priority) \
(((priority) >= 0) && ((priority) < (1U << (__NVIC_PRIO_BITS))))
/**@brief Macro to get the number of elements in an array.
*
* @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()
static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time)
{
uint64_t t1, u1;
uint64_t result;
/* The required range for time is [0..315360000000000], and the calculation below are
verified to work within broader range [0...2^49 ~ 17 years]
/* The required range for time is [0..315360000000000], and the calculation below is
verified to work within a broader range [0...2^49 ~ 17 years].
This first step in the calculation is to find out how many units
of 15625 us there are in the input_us, because 512 RTC units
corresponds _exactly_ to 15625 us. The calculation we want to do is therefore
t1 = time / 15625, but division is slow and therefore we want to calculate
t1 = time * k instead. The constant k is 1/15625 shifted up by as many bits
as we can without causing overflow during the calculation.
correspond _exactly_ to 15625 us. The desired calculation is therefore
t1 = time / 15625, but the division is slow and therefore let's calculate
t1 = time * k instead. The constant k is 1/15625, shifted up by as many bits
as possible without causing overflow during the calculation.
49 bits are needed to store the maximum value that time can have, and the
lowest 13 bits in that value can be shifted away because a minimum of 14 bits
are needed to store the divisor.
This means that time can be reduced to 49 - 13 = 36 bits to make space
This means that the time can be reduced to 49 - 13 = 36 bits to make space
for k.
The most suitable number of shift for the value 1 / 15625 = 0.000064
The most suitable number of shift for the value 1/15625 = 0.000064
(binary 0.00000000000001000011000110111101111...) is 41, because that results
in a 28 bits number that does not cause overflow in the multiplication.
in a 28-bit number that does not cause overflow in the multiplication.
(2^41)/15625) is equal to 0x8637bd0, and is written in hexadecimal representation
((2^41)/15625) is equal to 0x8637bd0, and is written in a hexadecimal representation
to show the bit width of the number. Shifting is limited to 41 bits because:
1 The time uses up to 49 bits, and
1 The time uses up to 49 bits;
2) The time can only be shifted down 13 bits to avoid shifting away
a full unit of 15625 microseconds, and
3) The maximum value of the calculation would otherwise overflow (i.e.
(315360000000000 >> 13) * 0x8637bd0 = 0x4b300bfcd0aefde0, would no longer be less than
a full unit of 15625 microseconds;
3) The maximum value of the calculation would otherwise overflow (that is,
(315360000000000 >> 13) * 0x8637bd0 = 0x4b300bfcd0aefde0 would no longer be less than
0Xffffffffffffffff).
There is a possible loss of precision so that t1 will be up to 93*15625 _smaller_
There is a possible loss of precision, so that t1 will be up to 93*15625 _smaller_
than the accurate number. This is taken into account in the next step.
*/
@@ -115,7 +122,7 @@ static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time)
/* This second step of the calculation is to find out how many RTC units there are
still left in the remaining microseconds.
(2^56)/15625) is equal to 0x431bde82d7b, and is written in hexadecimal representation
((2^56)/15625) is equal to 0x431bde82d7b, and is written in a hexadecimal representation
to show the bit width of the number. Shifting 56 bits is determined by the worst
case value of t1. The constant is selected by using the same methodology as in the
first step of the calculation above.
@@ -123,13 +130,13 @@ static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time)
The possible loss of precision in the calculation above can make t1 93*15625 lower
than it should have been here. The worst case found is that t1 can be 1453125, and
therefore there is no overflow in the calculation
1453125 * 0x431bde82d7b = 0x5cfffffffff76627 (i.e. it is less than 0xffffffffffffffff).
1453125 * 0x431bde82d7b = 0x5cfffffffff76627 (that is, it is less than 0xffffffffffffffff).
15625 below is the binary representation of 30.51757813 (11110.100001001)
scaled up by 2^9, and the calculation below are therefore using that scale.
Rounding up to the nearest RTC tick is done by adding the value of the least
significant bits of the fraction (i.e. adding the value of bits 1..47 of the scaled
significant bits of the fraction (that is, adding the value of bits 1..47 of the scaled
up timer unit size (2^47)) to the calculated value before scaling the final
value down to RTC ticks.*/
@@ -146,11 +153,11 @@ static inline uint64_t NRF_802154_US_TO_RTC_TICKS(uint64_t time)
/**@brief Checks if the provided interrupt is currently enabled.
*
* @note This function is valid only for ARM Cortex-M4 core.
* @note This function is valid only for the ARM Cortex-M4 core.
*
* @params IRQn Interrupt number.
*
* @returns Zero if interrupt is disabled, non-zero value otherwise.
* @returns Zero value if the interrupt is disabled; non-zero value otherwise.
*/
static inline uint32_t nrf_is_nvic_irq_enabled(IRQn_Type IRQn)
{
@@ -29,15 +29,15 @@
*/
/**
* @brief This module defines Clock Abstraction Layer for the 802.15.4 driver.
* @brief This module defines the Clock Abstraction Layer for the 802.15.4 driver.
*
* Clock Abstraction Layer can be used by other modules to start and stop nRF52840 clocks.
*
* It is used by Radio Arbiter clients (RAAL) to start HF clock when entering continuous mode
* and stop HF clock after continuous mode exit.
* It is used by the Radio Scheduler (RSCH) to start the HF clock when entering continuous mode
* and to stop the HF clock after exiting the continuous mode.
*
* It is used by standalone Low Power Timer Abstraction Layer implementation
* to start LF clock during initialization.
* It is also used by the standalone Low Power Timer Abstraction Layer implementation
* to start the LF clock during the initialization.
*
*/
@@ -59,64 +59,67 @@ extern "C" {
*/
/**
* @brief Initialize the clock driver.
* @brief Initializes the clock driver.
*/
void nrf_802154_clock_init(void);
/**
* @brief Deinitialize the clock driver.
* @brief Deinitializes the clock driver.
*/
void nrf_802154_clock_deinit(void);
/**
* @brief Start High Frequency Clock.
* @brief Starts the High Frequency Clock.
*
* This function is asynchronous, meant to request the ramp-up of the High Frequency Clock and exit.
* When the High Frequency Clock is ready, @ref nrf_802154_hfclk_ready() is called.
*
* This function is asynchronous. It should request ramping up of HF clock and exit. When HF clock
* is ready @sa nrf_802154_hfclk_ready() should be called.
*/
void nrf_802154_clock_hfclk_start(void);
/**
* @brief Stop High Frequency Clock.
* @brief Stops the High Frequency Clock.
*/
void nrf_802154_clock_hfclk_stop(void);
/**
* @brief Check if High Frequency Clock is running.
* @brief Checks if the High Frequency Clock is running.
*
* @retval true High Frequency Clock is running.
* @retval false High Frequency Clock is not running.
*
* @retval true If High Frequency Clock is running.
* @retval false If High Frequency Clock is not running.
*/
bool nrf_802154_clock_hfclk_is_running(void);
/**
* @brief Start Low Frequency Clock.
* @brief Starts the Low Frequency Clock.
*
* This function is asynchronous, meant to request the ramp-up of the Low Frequency Clock and exit.
* When the Low Frequency Clock is ready, @ref nrf_802154_lfclk_ready() is called.
*
* This function is asynchronous. It should request ramping up of LF clock and exit. When LF clock
* is ready @sa nrf_802154_lfclk_ready() should be called.
*/
void nrf_802154_clock_lfclk_start(void);
/**
* @brief Stop Low Frequency Clock.
* @brief Stops the Low Frequency Clock.
*/
void nrf_802154_clock_lfclk_stop(void);
/**
* @brief Check if Low Frequency Clock is running.
* @brief Checks if the Low Frequency Clock is running.
*
* @retval true If Low Frequency Clock is running.
* @retval false If Low Frequency Clock is not running.
* @retval true Low Frequency Clock is running.
* @retval false Low Frequency Clock is not running.
*/
bool nrf_802154_clock_lfclk_is_running(void);
/**
* @brief Callback executed when High Frequency Clock is ready.
* @brief Callback function executed when the High Frequency Clock is ready.
*/
extern void nrf_802154_clock_hfclk_ready(void);
/**
* @brief Callback executed when Low Frequency Clock is ready.
* @brief Callback function executed when the Low Frequency Clock is ready.
*/
extern void nrf_802154_clock_lfclk_ready(void);
@@ -41,11 +41,15 @@
#include <nrf_clock.h>
#include "nrf_802154_config.h"
#include "nrf_802154_utils.h"
void nrf_802154_clock_init(void)
{
nrf_clock_lf_src_set(NRF_802154_CLOCK_LFCLK_SOURCE);
#if !NRF_IS_IRQ_PRIORITY_ALLOWED(NRF_802154_CLOCK_IRQ_PRIORITY)
#error NRF_802154_CLOCK_IRQ_PRIORITY value out of the allowed range.
#endif
NVIC_SetPriority(POWER_CLOCK_IRQn, NRF_802154_CLOCK_IRQ_PRIORITY);
NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn);
NVIC_EnableIRQ(POWER_CLOCK_IRQn);
@@ -86,19 +86,19 @@ void nrf_802154_hp_timer_deinit(void)
void nrf_802154_hp_timer_start(void)
{
#if !RAAL_SOFTDEVICE && !RAAL_SIMULATOR
#if !RAAL_SOFTDEVICE && !RAAL_SIMULATOR && !RAAL_REM
nrf_timer_mode_set(TIMER, NRF_TIMER_MODE_TIMER);
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
#endif // !RAAL_SOFTDEVICE && !RAAL_SIMULATOR && !RAAL_REM
}
void nrf_802154_hp_timer_stop(void)
{
#if !RAAL_SOFTDEVICE && !RAAL_SIMULATOR
#if !RAAL_SOFTDEVICE && !RAAL_SIMULATOR && !RAAL_REM
nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_SHUTDOWN);
#endif // !RAAL_SOFTDEVICE && !RAAL_SIMULATOR
#endif // !RAAL_SOFTDEVICE && !RAAL_SIMULATOR && !RAAL_REM
}
uint32_t nrf_802154_hp_timer_sync_task_get(void)
@@ -29,7 +29,7 @@
*/
/**
* @brief This module defines API or High Precision Timer for the 802.15.4 driver.
* @brief Module that defines API of High Precision Timer for the 802.15.4 driver.
*
*/
@@ -49,88 +49,91 @@ extern "C" {
* @ingroup nrf_802154_hp_timer
* @brief High Precision Timer for the 802.15.4 driver.
*
* High Precision Timer is a timer that is used only when the radio is in use. This timer is not
* used when the radio is in the sleep mode or out of RAAL timeslots. This timer should provide at
* least 1us precision. It is intended to be used for precise frame timestamps or synchronous radio
* operations.
* The High Precision Timer is used only when the radio is in use. It is not
* used when the radio is in the sleep mode or out of the RAAL timeslots.
* This timer is meant to provide at least 1-microsecond precision. It is intended to be used
* for precise frame timestamps or synchronous radio operations.
*
* @note High Precision Timer is a relative timer. To use it as absolute timer it must be
* synchronized with the Low Power Timer.
* @note The High Precision Timer is relative. To use it as an absolute timer,
* synchronize it with the Low Power Timer using the Timer Coordinator module.
*
*/
/**
* @brief Initialize the timer.
* @brief Initializes the timer.
*/
void nrf_802154_hp_timer_init(void);
/**
* @brief Uninitialize the timer.
* @brief Deinitializes the timer.
*/
void nrf_802154_hp_timer_deinit(void);
/**
* @brief Start the timer.
* @brief Starts the timer.
*
* The timer starts counting when this command is called.
*/
void nrf_802154_hp_timer_start(void);
/**
* @brief Stop the timer.
* @brief Stops the timer.
*
* The timer stops counting and enters low power mode.
* The timer stops counting and enters the low power mode.
*/
void nrf_802154_hp_timer_stop(void);
/**
* @brief Get value indicated by the timer right now.
* @brief Gets the value indicated by the timer right now.
*
* @note Returned value is relative to the @ref nrf_802154_hp_timer_start call time. It is not
* synchronized with the lp timer.
* @note The returned value is relative to the @ref nrf_802154_hp_timer_start call time. It is not
* synchronized with the LP timer.
*
* @returns Current timer value in microseconds.
*
* @returns Current timer value [us].
*/
uint32_t nrf_802154_hp_timer_current_time_get(void);
/**
* @brief Get task used to synchronize this timer with the LP timer.
* @brief Gets the task used to synchronize the timer with the LP timer.
*
* @returns Address of the task.
*
*/
uint32_t nrf_802154_hp_timer_sync_task_get(void);
/**
* @brief Configure the timer to detect if sync task was triggered.
* @brief Configures the timer to detect if the synchronization task was triggered.
*/
void nrf_802154_hp_timer_sync_prepare(void);
/**
* @brief Get timestamp of the synchronization event.
* @brief Gets the timestamp of the synchronization event.
*
* @param[out] p_timestamp Timestamp of the synchronization event.
*
* @retval true Synchronization was performed and @p p_timestamp is valid.
* @retval false Synchronization was not performed. @p p_timestamp was not modified.
*
*/
bool nrf_802154_hp_timer_sync_time_get(uint32_t * p_timestamp);
/**
* @brief Get task used to make timestamp of an event.
* @brief Gets the task used to make timestamp of an event.
*
* This function should be used to configure PPI.
* This function configures the timer in order to detect if returned task was triggered to return
* valid value by the @ref nrf_802154_hp_timer_timestamp_get.
* This function is to be used to configure PPI.
* It configures the timer to detect if the returned task was triggered to return
* a valid value by @ref nrf_802154_hp_timer_timestamp_get.
*
* @returns Address of the task.
*/
uint32_t nrf_802154_hp_timer_timestamp_task_get(void);
/**
* @brief Get timestamp of last event.
* @brief Gets the timestamp of the last event.
*
* @returns Timestamp of last event that triggered the @ref nrf_802154_hp_timer_timestamp_task_get
* task.
* @returns Timestamp of the last event that triggered
* the @ref nrf_802154_hp_timer_timestamp_task_get task.
*/
uint32_t nrf_802154_hp_timer_timestamp_get(void);
@@ -29,7 +29,7 @@
*/
/**
* @brief This module defines Low Power Timer Abstraction Layer for the 802.15.4 driver.
* @brief Module that defines the Low Power Timer Abstraction Layer for the 802.15.4 driver.
*
*/
@@ -49,95 +49,97 @@ extern "C" {
* @ingroup nrf_802154_timer
* @brief Low Power Timer Abstraction Layer interface for the 802.15.4 driver.
*
* Low Power Timer Abstraction Layer is an abstraction layer of timer that is meant to be used by
* the nRF 802.15.4 driver. This timer should provide low latency (max 100 us) in order to allow
* implementation in the driver code features like:
* * Timing out waiting for ACK frame
* The Low Power Timer Abstraction Layer is an abstraction layer of the timer that is meant
* to be used by the nRF 802.15.4 driver. This timer is intended to provide low latency
* (max. 100 microseconds) to allow the implementation of the following features in the driver code:
* * Timing out when waiting for an ACK frame
* * SIFS and LIFS
* * CSMA/CA
* * CSL
* * Auto polling by rx-off-when-idle devices
*
* @note Most of Low Power Timer Abstraction Layer API should not be called directly by 802.15.4 driver
* modules. This API is used by the Timer Scheduler module included in the driver and other
* modules should use Timer Scheduler API. Exception from above rule are initialization and
* deinitialization functions @sa nrf_802154_lp_timer_init()
* @sa nrf_802154_lp_timer_deinit() and critical section management
* @sa nrf_802154_lp_timer_critical_section_enter()
* @sa nrf_802154_lp_timer_critical_section_exit() as these functions are called from
* nrf_802154_critical_section module and from global initialization functions
* @sa nrf_802154_init() @sa nrf_802154_deinit().
* @note Most of the Low Power Timer Abstraction Layer API is not intended to be called directly
* by the 802.15.4 driver modules. This API is used by the Timer Scheduler module included
* in the driver. Other modules should use the Timer Scheduler API. The exception are
* initialization and deinitialization functions @ref nrf_802154_lp_timer_init() and
* @ref nrf_802154_lp_timer_deinit(), as well as critical section management
* @ref nrf_802154_lp_timer_critical_section_enter() and
* @ref nrf_802154_lp_timer_critical_section_exit(), as these functions are called from
* the nrf_802154_critical_section module and from the global initialization
* and deinitialization functions @ref nrf_802154_init() and @ref nrf_802154_deinit().
*/
/**
* @brief Initialize the Timer.
* @brief Initializes the Timer.
*/
void nrf_802154_lp_timer_init(void);
/**
* @brief Uninitialize the Timer.
* @brief Deinitializes the Timer.
*/
void nrf_802154_lp_timer_deinit(void);
/**
* @brief Enter critical section of the timer.
* @brief Enters the critical section of the timer.
*
* In critical section timer cannot execute @sa nrf_802154_lp_timer_fired() function.
* In the critical section, the timer cannot execute the @ref nrf_802154_lp_timer_fired() function.
*
* @note The critical section cannot be nested.
*
* @note Critical section cannot be nested.
*/
void nrf_802154_lp_timer_critical_section_enter(void);
/**
* @brief Exit critical section of the timer.
* @brief Exits the critical section of the timer.
*
* In critical section timer cannot execute @sa nrf_802154_lp_timer_fired() function.
* In the critical section, the timer cannot execute the @ref nrf_802154_lp_timer_fired() function.
*
* @note Critical section cannot be nested.
* @note The critical section cannot be nested.
*/
void nrf_802154_lp_timer_critical_section_exit(void);
/**
* @brief Get current time.
* @brief Gets the current time.
*
* Prior to getting current time, Timer must be initialized @sa nrf_802154_lp_timer_init().
* There are no other requirements that must be fulfilled before using this function.
* @pre Before getting the current time, the timer must be initialized with
* @ref nrf_802154_lp_timer_init(). This is the only requirement that must be met before using this
* function.
*
* @return Current time in microseconds [us].
* @returns Current time in microseconds.
*/
uint32_t nrf_802154_lp_timer_time_get(void);
/**
* @brief Get granularity of currently used timer.
* @brief Gets the granularity of the timer.
*
* This function may be used to round up/down time calculations.
* This function can be used to round up or round down the time calculations.
*
* @return Timer granularity in microseconds [us].
* @returns Timer granularity in microseconds.
*/
uint32_t nrf_802154_lp_timer_granularity_get(void);
/**
* @brief Start one-shot timer that expires at specified time.
* @brief Starts a one-shot timer that expires at the specified time.
*
* Start one-shot timer that will expire @p dt microseconds after @p t0 time.
* If timer is running when this function is called, previously running timer will be stopped
* This function starts a one-shot timer that will expire @p dt microseconds after @p t0 time.
* If the timer is running when this function is called, the running timer is stopped
* automatically.
*
* On timer expiration @sa nrf_802154_lp_timer_fired function will be called.
* Timer automatically stops after expiration.
* On timer expiration, the @ref nrf_802154_lp_timer_fired function will be called.
* The timer stops automatically after the expiration.
*
* @param[in] t0 Number of microseconds representing timer start time.
* @param[in] dt Time of timer expiration as time elapsed from @p t0 [us].
* @param[in] dt Time of the timer expiration as time elapsed from @p t0, in microseconds.
*/
void nrf_802154_lp_timer_start(uint32_t t0, uint32_t dt);
/**
* @brief Stop currently running timer.
* @brief Stops the currently running timer.
*/
void nrf_802154_lp_timer_stop(void);
/**
* @brief Check if timer is currently running.
* @brief Checks if the timer is currently running.
*
* @retval true Timer is running.
* @retval false Timer is not running.
@@ -145,55 +147,57 @@ void nrf_802154_lp_timer_stop(void);
bool nrf_802154_lp_timer_is_running(void);
/**
* @brief Start one-shot synchronization timer that expires at nearest possible timepoint.
* @brief Starts a one-shot synchronization timer that expires at the nearest possible timepoint.
*
* On timer expiration @ref nrf_802154_lp_timer_synchronized function will be called and
* event returned by @ref nrf_802154_lp_timer_sync_event_get will be triggered.
* On timer expiration, the @ref nrf_802154_lp_timer_synchronized function is called and the
* event returned by @ref nrf_802154_lp_timer_sync_event_get is triggered.
*
* @note @ref nrf_802154_lp_timer_synchronized may be called multiple times.
*/
void nrf_802154_lp_timer_sync_start_now(void);
/**
* @brief Start one-shot synchronization timer that expires at specified time.
* @brief Starts a one-shot synchronization timer that expires at the specified time.
*
* Start one-shot synchronization timer that will expire @p dt microseconds after @p t0 time.
* This function starts a one-shot synchronization timer that expires @p dt microseconds after
* @p t0 time.
*
* On timer expiration @ref nrf_802154_lp_timer_synchronized function will be called and
* event returned by @ref nrf_802154_lp_timer_sync_event_get will be triggered.
* On timer expiration, @ref nrf_802154_lp_timer_synchronized function is called and
* the event returned by @ref nrf_802154_lp_timer_sync_event_get is triggered.
*
* @param[in] t0 Number of microseconds representing timer start time.
* @param[in] dt Time of timer expiration as time elapsed from @p t0 [us].
* @param[in] t0 Number of microseconds that represents the timer start time.
* @param[in] dt Time of the timer expiration as time elapsed from @p t0, in microseconds.
*/
void nrf_802154_lp_timer_sync_start_at(uint32_t t0, uint32_t dt);
/**
* @brief Stop currently running synchronization timer.
* @brief Stops the currently running synchronization timer.
*/
void nrf_802154_lp_timer_sync_stop(void);
/**
* @brief Get event used to synchronize this timer with HP Timer
* @brief Gets the event used to synchronize this timer with the HP Timer.
*
* @returns Address of the peripheral register corresponding to the event
* to be used for the timer synchronization.
*
* @return Address of the peripheral register corresponding to the event that
* should be used for timers synchronization.
*/
uint32_t nrf_802154_lp_timer_sync_event_get(void);
/**
* @brief Get timestamp of the synchronization event.
* @brief Gets the timestamp of the synchronization event.
*
* @return Timestamp of the synchronization event.
* @returns Timestamp of the synchronization event.
*/
uint32_t nrf_802154_lp_timer_sync_time_get(void);
/**
* @brief Callback executed when timer expires.
* @brief Callback function executed when the timer expires.
*/
extern void nrf_802154_lp_timer_fired(void);
/**
* @brief Callback executed when synchronization timer expires.
* @brief Callback function executed when the synchronization timer expires.
*/
extern void nrf_802154_lp_timer_synchronized(void);
@@ -405,6 +405,9 @@ void nrf_802154_lp_timer_init(void)
}
// Setup RTC timer.
#if !NRF_IS_IRQ_PRIORITY_ALLOWED(NRF_802154_RTC_IRQ_PRIORITY)
#error NRF_802154_RTC_IRQ_PRIORITY value out of the allowed range.
#endif
NVIC_SetPriority(NRF_802154_RTC_IRQN, NRF_802154_RTC_IRQ_PRIORITY);
NVIC_ClearPendingIRQ(NRF_802154_RTC_IRQN);
NVIC_EnableIRQ(NRF_802154_RTC_IRQN);
@@ -29,7 +29,7 @@
*/
/**
* @brief This module defines Pseudo-random number generator Abstraction Layer.
* @brief Module that defines the pseudo-random number generator Abstraction Layer.
*
*/
@@ -47,27 +47,27 @@ extern "C" {
* @defgroup nrf_802154_random Random Abstraction Layer for the 802.15.4 driver
* @{
* @ingroup nrf_802154_random
* @brief Pseudo-random number generator Abstraction Layer interface for the 802.15.4 driver.
* @brief The pseudo-random number generator Abstraction Layer interface for the 802.15.4 driver.
*
* Random Abstraction Layer is an abstraction layer of a pseudo-random number generator that is used
* to perform CSMA-CA procedure correctly.
* The Random Abstraction Layer is an abstraction layer of a pseudo-random number generator that is
* used to perform CSMA-CA procedure correctly.
*
*/
/**
* @brief Initialize random number generator.
* @brief Initializes the random number generator.
*/
void nrf_802154_random_init(void);
/**
* @brief Uninitialize random number generator.
* @brief Deinitializes the random number generator.
*/
void nrf_802154_random_deinit(void);
/**
* @brief Get a pseudo-random number.
* @brief Gets a pseudo-random number.
*
* @return Pseudo-random number.
* @returns Pseudo-random number.
*/
uint32_t nrf_802154_random_get(void);
@@ -29,7 +29,7 @@
*/
/**
* @brief This module defines Thermometer Abstraction Layer for the 802.15.4 driver.
* @brief Module that defines the Thermometer Abstraction Layer for the 802.15.4 driver.
*
*/
@@ -47,32 +47,32 @@ extern "C" {
* @defgroup nrf_802154_temperature Thermometer Abstraction Layer for the 802.15.4 driver
* @{
* @ingroup nrf_802154_temperature
* @brief Thermometer Abstraction Layer interface for the 802.15.4 driver.
* @brief The Thermometer Abstraction Layer interface for the 802.15.4 driver.
*
* Thermometer Abstraction Layer is an abstraction layer of thermometer that is used to correct
* RSSI, LQI, ED result and CCA threshold measurements.
* The Thermometer Abstraction Layer is an abstraction layer of the thermometer that is used
* to correct RSSI, LQI and ED measurements, and the CCA threshold value.
*
*/
/**
* @brief Initialize thermometer.
* @brief Initializes the thermometer.
*/
void nrf_802154_temperature_init(void);
/**
* @brief Uninitialize thermometer.
* @brief Deinitializes the thermometer.
*/
void nrf_802154_temperature_deinit(void);
/**
* @brief Get current temperature.
* @brief Gets the current temperature.
*
* @return Current temperature [C].
* @returns Current temperature, in centigrades (C).
*/
int8_t nrf_802154_temperature_get(void);
/**
* @brief Callback executed when temperature changes.
* @brief Callback function executed when the temperature changes.
*/
extern void nrf_802154_temperature_changed(void);
@@ -328,6 +328,7 @@ static void delayed_timeslot_start(void * p_context)
p_dly_ts->prio = RSCH_PRIO_IDLE;
all_prec_update();
notify_core();
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_RSCH_TIMER_DELAYED_START);
}
@@ -384,7 +385,7 @@ 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);
nrf_802154_timer_sched_remove(&m_dly_ts[i].timer, NULL);
}
nrf_raal_uninit();
@@ -401,11 +402,6 @@ void nrf_802154_rsch_continuous_mode_priority_set(rsch_prio_t prio)
all_prec_update();
notify_core();
if (prio == RSCH_PRIO_IDLE)
{
m_last_notified_prio = RSCH_PRIO_IDLE;
}
nrf_802154_log(EVENT_TRACE_EXIT, (prio > RSCH_PRIO_IDLE) ? FUNCTION_RSCH_CONTINUOUS_ENTER :
FUNCTION_RSCH_CONTINUOUS_EXIT);
}
@@ -481,6 +477,28 @@ bool nrf_802154_rsch_delayed_timeslot_request(uint32_t t0,
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;
@@ -29,7 +29,7 @@
*/
/**
* @brief This module defines Radio Scheduler interface.
* @brief Module that defines the Radio Scheduler interface.
*
*/
@@ -47,18 +47,18 @@ extern "C" {
* @defgroup nrf_rsch Radio Scheduler
* @{
* @ingroup nrf_802154
* @brief Radio Scheduler interface.
* @brief The Radio Scheduler interface.
*
* Radio Scheduler is responsible to schedule in time radio activities and preconditions. It is
* expected that the Radio Scheduler module manages timings to meet requirements requested from the
* core module.
* Radio Scheduler is responsible to schedule radio activities and preconditions in time. It is
* expected that the Radio Scheduler module manages timings to meet the requirements requested from
* the core module.
*
* Examples of radio activity preconditions are: High-Frequency Clock running, radio arbiter (RAAL)
* Examples of the radio activity preconditions are: High-Frequency Clock running, radio arbiter (RAAL)
* granted access to the RADIO peripheral.
*/
/**
* @brief List of preconditions that have to be met before any radio activity.
* @brief List of the preconditions that have to be met before any radio activity.
*/
typedef enum
{
@@ -72,54 +72,52 @@ typedef enum
*/
typedef enum
{
RSCH_PRIO_IDLE, ///< Priority used in the sleep state. With this priority RSCH releases all preconditions.
RSCH_PRIO_IDLE, ///< Priority used in the sleep state. With this priority, RSCH releases all preconditions.
RSCH_PRIO_IDLE_LISTENING, ///< Priority used during the idle listening procedure.
RSCH_PRIO_RX, ///< Priority used when a frame is being received.
RSCH_PRIO_DETECT, ///< Priority used to detect channel conditions (CCA, ED).
RSCH_PRIO_TX, ///< Priority used to transmit a frame.
RSCH_PRIO_MIN_APPROVED = RSCH_PRIO_IDLE_LISTENING, ///< Minimal priority indicating that given precondition is approved.
RSCH_PRIO_MIN_APPROVED = RSCH_PRIO_IDLE_LISTENING, ///< Minimal priority indicating that the given precondition is approved.
RSCH_PRIO_MAX = RSCH_PRIO_TX, ///< Maximal priority available in the RSCH module.
} rsch_prio_t;
/**
* @brief Enumeration of delayed timeslots ids.
* @brief Enumeration of the delayed timeslot IDs.
*/
typedef enum
{
RSCH_DLY_TX, ///< Timeslot for delayed tx operation.
RSCH_DLY_RX, ///< Timeslot for delayed rx operation.
RSCH_DLY_TX, ///< Timeslot for delayed TX operation.
RSCH_DLY_RX, ///< Timeslot for delayed RX operation.
RSCH_DLY_TS_NUM, ///< Number of delayed timeslots.
} rsch_dly_ts_id_t;
/**
* @brief Initialize Radio Scheduler.
* @brief Initializes Radio Scheduler.
*
* @note This function shall be called once, before any other function from this module.
* @note This function must be called once, before any other function from this module.
*
* Initialize Radio Scheduler.
*
* @note Radio Scheduler starts in inactive mode after initialization. In order to start radio activity
* @note Radio Scheduler starts in the inactive mode after the initialization. To start the radio activity,
* @ref nrf_802154_rsch_continuous_mode_enter should be called.
*
*/
void nrf_802154_rsch_init(void);
/**
* @brief Uninitialize Radio Scheduler.
* @brief Deinitializes Radio Scheduler.
*
*/
void nrf_802154_rsch_uninit(void);
/**
* @brief Set priority for the continuous radio mode.
* @brief Sets the priority for the continuous radio mode.
*
* In the continuous mode the radio scheduler should try to satisfy all preconditions as long as
* possible in order to give to the radio driver core as much radio time as possible while
* disturbing the other activities as little as possible.
* In the continuous mode, Radio Scheduler tries to satisfy all preconditions for as long as
* possible to give the radio driver core as much radio time as possible while
* disturbing the other activities to the minimum extent.
*
* @note The start of a timeslot will be indicated by @ref nrf_802154_rsch_prec_approved call.
* @note The start of a timeslot is indicated by the @ref nrf_802154_rsch_prec_approved call.
* @note To disable the continuous radio mode, the @ref RSCH_PRIO_IDLE should be used.
*
* @param[in] prio Priority level used in the continuous radio mode.
@@ -128,23 +126,23 @@ void nrf_802154_rsch_uninit(void);
void nrf_802154_rsch_continuous_mode_priority_set(rsch_prio_t prio);
/**
* @brief Confirm that current part of continuous timeslot is ended by the core.
* @brief Confirms that the current part of the continuous timeslot is ended by the core.
*
* This confirmation is used by the core to synchronize ending of continuous timeslot parts with
* This confirmation is used by the core to synchronize the ending of the continuous timeslot parts with
* the RSCH module.
*
*/
void nrf_802154_rsch_continuous_ended(void);
/**
* @brief Request timeslot for radio communication immediately.
* @brief Immediately requests a timeslot for radio communication.
*
* This function should be called only after @ref nrf_802154_rsch_prec_approved indicated the
* This function is to be called only after @ref nrf_802154_rsch_prec_approved indicated the
* start of a timeslot.
*
* @param[in] length_us Requested radio timeslot length in microsecond.
* @param[in] length_us Requested radio timeslot length in microseconds.
*
* @retval true The radio driver now has exclusive access to the RADIO peripheral for the
* @retval true Radio driver has now exclusive access to the RADIO peripheral for the
* full length of the timeslot.
* @retval false Slot cannot be assigned due to other activities.
*
@@ -152,20 +150,20 @@ void nrf_802154_rsch_continuous_ended(void);
bool nrf_802154_rsch_timeslot_request(uint32_t length_us);
/**
* @brief Request timeslot in the future.
* @brief Requests a timeslot in the future.
*
* Request timeslot that should be granted in the future. Function parameters provides data when
* the timeslot should start and how long should it last. When requested timeslot starts the
* 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.
*
* @note @ref nrf_802154_rsch_delayed_timeslot_started may be delayed and it is up to
* @note @ref nrf_802154_rsch_delayed_timeslot_started can be delayed and it is up to
* the called module to check the delay and decide if it causes any issues.
*
* @note Time parameters use the same units that are used in the Timer Scheduler module.
* @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 [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] 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.
*
@@ -179,9 +177,20 @@ bool nrf_802154_rsch_delayed_timeslot_request(uint32_t t0,
rsch_dly_ts_id_t dly_ts);
/**
* @brief Check if there is a pending timeslot request.
* @brief Cancels a requested future timeslot.
*
* @note Delayed timeslot is considered requested once its preconditions are granted.
* @param[in] dly_ts_id Type 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 Checks if there is a pending timeslot request.
*
* @note The delayed timeslot is considered requested once its preconditions are requested
* or granted.
*
* @retval true There is a timeslot request pending.
* @retval false There are no pending timeslot requests.
@@ -189,10 +198,10 @@ bool nrf_802154_rsch_delayed_timeslot_request(uint32_t t0,
bool nrf_802154_rsch_timeslot_is_requested(void);
/**
* @brief Check if the RSCH precondition is satisfied.
* @brief Checks if the RSCH precondition is satisfied.
*
* @param[in] prec RSCH precondition to be checked.
* @param[in] prio Minimal required priority level of given precondition.
* @param[in] prio Minimal required priority level of the given precondition.
*
* @retval true Precondition @p prec is currently granted.
* @retval false Precondition @p prec is not currently granted.
@@ -200,26 +209,26 @@ bool nrf_802154_rsch_timeslot_is_requested(void);
bool nrf_802154_rsch_prec_is_approved(rsch_prec_t prec, rsch_prio_t prio);
/**
* @brief Get left time of currently granted timeslot [us].
* @brief Gets the remaining time of the currently granted timeslot, in microseconds.
*
* @returns Number of microseconds left in currently granted timeslot.
* @returns Number of microseconds remaining in the currently granted timeslot.
*/
uint32_t nrf_802154_rsch_timeslot_us_left_get(void);
/**
* @brief This function is called to notify the core about changes of approved priority level.
* @brief Notifies the core about changes of the approved priority level.
*
* If the @p prio is greater than @ref RSCH_PRIO_IDLE, the radio driver has exclusive access to the
* peripherals until this function is called with the @p prio equal to @ref RSCH_PRIO_IDLE.
* If @p prio is greater than @ref RSCH_PRIO_IDLE, the radio driver has exclusive access to the
* peripherals until this function is called with @p prio equal to @ref RSCH_PRIO_IDLE.
*
* @note The end of the timeslot is indicated by @p prio equal to the @ref RSCH_PRIO_IDLE.
* @note The end of the timeslot is indicated by @p prio equal to @ref RSCH_PRIO_IDLE.
*
* @param[in] prio Currently approved priority level.
*/
extern void nrf_802154_rsch_continuous_prio_changed(rsch_prio_t prio);
/**
* @brief Notification that previously requested delayed timeslot has started just now.
* @brief Notifies that the previously requested delayed timeslot has started just now.
*
* @param[in] dly_ts_id Type of the started timeslot.
*/
@@ -39,26 +39,26 @@
* @defgroup nrf_802154_rsch_crit_sect RSCH event queue used during critical sections
* @{
* @ingroup nrf_802154_rsch
* @brief Critical section implementation for the RSCH module.
* @brief The critical section implementation for the RSCH module.
*/
/**
* @brief Initialize the RSCH critical section module.
* @brief Initializes the RSCH critical section module.
*/
void nrf_802154_rsch_crit_sect_init(void);
/**
* @brief Request priority level from RSCH through the critical section module.
* @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 This function is called to notify the core that approved RSCH priority has changed.
* @brief Notifies the core that the approved RSCH priority has changed.
*
* @note This function is called from critical section context and does not preempt other critical
* sections.
* @note This function is called from the critical section context and does not preempt
* other critical sections.
*
* @param[in] prio Approved priority level.
*/
@@ -29,7 +29,7 @@
*/
/**
* @brief This module defines the Wifi coexistence module.
* @brief Module that defines the Wi-Fi coexistence module.
*
*/
@@ -43,57 +43,57 @@ extern "C" {
#endif
/**
* @defgroup nrf_wifi_coex Wifi Coexistence
* @defgroup nrf_wifi_coex Wi-Fi Coexistence
* @{
* @ingroup nrf_802154
* @brief Wifi Coexistence module.
* @brief The Wi-Fi Coexistence module.
*
* Wifi Coexistence module is a client of the PTA (defined in the 802.15.2). It manages GPIO
* 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 Initialize the Wifi Coexistence module.
* @brief Initializes the Wi-Fi Coexistence module.
*
* @note This function shall be called once, before any other function from this module.
* @note This function must be called once, before any other function from this module.
*
*/
void nrf_802154_wifi_coex_init(void);
/**
* @brief Uninitialize the Wifi Coexistence module.
* @brief Deinitializes the Wi-Fi Coexistence module.
*
*/
void nrf_802154_wifi_coex_uninit(void);
/**
* @brief Request given priority from the Wifi Coexistence module.
* @brief Requests the given priority from the Wi-Fi Coexistence module.
*
* @note The approval of requested priority is notified asynchronously by the
* @note The approval of the requested priority is notified asynchronously by the
* @ref nrf_802154_wifi_coex_prio_changed call.
*
* @param[in] priority Requested priority level.
* @param[in] priority The requested priority level.
*
*/
void nrf_802154_wifi_coex_prio_req(rsch_prio_t priority);
/**
* @brief Get priority denial event address.
* @brief Gets the priority denial event address.
*
* Get an address of a hardware event that notifies about denial of the previously approved
* Get the address of a hardware event that notifies about the denial of a previously approved
* priority.
*
* @return Address of a priority denial event.
* @returns Address of the priority denial event.
*/
void * nrf_802154_wifi_coex_deny_event_addr_get(void);
/**
* @biref Approved priority change notification.
* @brief Notifies about the approved priority change.
*
* The Wifi Coexistence module calls this function to notify the RSCH of currently approved
* The Wi-Fi Coexistence module calls this function to notify the RSCH of the currently approved
* priority level.
*
* @param[in] priority Approved priority level.
* @param[in] priority The approved priority level.
*/
extern void nrf_802154_wifi_coex_prio_changed(rsch_prio_t priority);
@@ -29,7 +29,7 @@
*/
/**
* @brief This module defines Radio Arbiter Abstraction Layer interface.
* @brief Module that defines the Radio Arbiter Abstraction Layer interface.
*
*/
@@ -47,133 +47,104 @@ extern "C" {
* @defgroup nrf_raal Radio Arbiter Abstraction Layer
* @{
* @ingroup nrf_802154
* @brief Radio Arbiter Abstraction Layer interface.
* @brief The Radio Arbiter Abstraction Layer interface.
*/
/**
* @brief Initialize RAAL.
* @brief Initializes Radio Arbiter Abstraction Layer client.
*
* @note This function shall be called once, before any other function from this module.
* This function must be called once, before any other function from this module.
*
* Initialize Radio Arbiter Abstraction Layer client.
*
* @note Arbiter starts in inactive mode after initialization. In order to start radio activity
* @p nrf_raal_continuous_mode_enter method should be called.
* @note The arbiter starts in the inactive mode after the initialization.
* To start the radio activity, the @p nrf_raal_continuous_mode_enter method must be called.
*
*/
void nrf_raal_init(void);
/**
* @brief Uninitialize RAAL.
*
* Uninitialize Radio Arbiter Abstraction Layer client.
* @brief Deinitializes Radio Arbiter Abstraction Layer client.
*
*/
void nrf_raal_uninit(void);
/**
* @brief Enter arbiter into continuous radio mode.
* @brief Puts the arbiter into the continuous radio mode.
*
* In this mode radio arbiter should try to create long continuous timeslots that will give the
* radio driver as much radio time as possible while disturbing the other activities as little
* In this mode, the radio arbiter tries to create long continuous timeslots that will give
* the radio driver as much radio time as possible while disturbing the other activities as little
* as possible.
* The arbiter client shall make sure that high frequency clock is enabled in each timeslot.
*
* @note The start of a timeslot will be indicated by @p nrf_raal_timeslot_started call.
* @note The start of a timeslot is indicated by the @p nrf_raal_timeslot_started call.
*
*/
void nrf_raal_continuous_mode_enter(void);
/**
* @brief Exit arbiter from continuous mode.
* @brief Moves the arbiter out of the continuous mode.
*
* In this mode radio arbiter will not extend or allocate any more timeslots for radio driver.
* In this mode, the radio arbiter does not extend or allocate any more timeslots for
* the radio driver.
*
*/
void nrf_raal_continuous_mode_exit(void);
/**
* @brief Confirm to RAAL that current part of the continuous timeslot is ended.
* @brief Sends a confirmation to RAAL that the current part of the continuous timeslot is ended.
*
* The core cannot use the RADIO peripheral after this call until the timeslot is started again.
*/
void nrf_raal_continuous_ended(void);
/**
* @brief Request timeslot for radio communication.
* @brief Requests a timeslot for radio communication.
*
* This method should be called only after @p nrf_raal_timeslot_started indicated the start
* This method is to be called only after @p nrf_raal_timeslot_started indicated the start
* of a timeslot.
*
* @param[in] length_us Requested radio timeslot length in microsecond.
* @param[in] length_us Requested radio timeslot length in microseconds.
*
* @retval TRUE The radio driver now has exclusive access to the RADIO peripheral for the
* @retval true Radio driver has now exclusive access to the RADIO peripheral for the
* full length of the timeslot.
* @retval FALSE Slot cannot be assigned due to other activities.
* @retval false Slot cannot be assigned due to other activities.
*
*/
bool nrf_raal_timeslot_request(uint32_t length_us);
/**
* @brief Get left time of currently granted timeslot [us].
* @brief Gets the remaining time of the currently granted timeslot, in microseconds.
*
* @returns Number of microseconds left in currently granted timeslot.
* @returns Number of microseconds left in the currently granted timeslot.
*/
uint32_t nrf_raal_timeslot_us_left_get(void);
/**
* @brief Enter critical section of the module.
* @brief Notifies the radio driver about the start of a timeslot. Called by the RAAL client.
*
* When this method is called, the execution of the @sa nrf_raal_timeslot_started and
* @sa nrf_raal_timeslot_ended function is blocked.
*
* @note This function may be called when RAAL is already in critical section. Ongoing call may
* be interrupted by another call from IRQ with higher priority.
*
*/
void nrf_raal_critical_section_enter(void);
/**
* @brief Exit critical section of the module.
*
* When this method is called driver has to expect the execution of the
* @sa nrf_raal_timeslot_started or @sa nrf_raal_timeslot_ended
* function.
*
* @note This function may be called when RAAL has already exited critical section. Ongoing call
* may NOT be interrupted by another call from IRQ with higher priority.
*/
void nrf_raal_critical_section_exit(void);
/**
* @brief RAAL client calls this method to notify radio driver about the start of a timeslot.
*
* The radio driver now has exclusive access to the peripherals until @p nrf_raal_timeslot_ended
* The radio driver has now exclusive access to the peripherals until @p nrf_raal_timeslot_ended
* is called.
*
* @note The high frequency clock must be enabled when this function is called.
* @note The end of the timeslot will be indicated by @p nrf_raal_timeslot_ended function.
* @note The end of the timeslot is indicated by the @p nrf_raal_timeslot_ended function.
*
*/
extern void nrf_raal_timeslot_started(void);
/**
* @brief RAAL client calls this method to notify radio driver about the end of a timeslot.
* @brief Notifies the radio driver about the end of a timeslot. Called by the RAAL client.
*
* Depending on the RAAL client configuration, radio driver has NRF_RAAL_MAX_CLEAN_UP_TIME_US
* microseconds to do any clean-up actions on RADIO peripheral and stop using it completely.
* Thus arbiter has to call this function NRF_RAAL_MAX_CLEAN_UP_TIME_US microseconds before
* timeslot is finished.
* Depending on the RAAL client configuration, the radio driver has NRF_RAAL_MAX_CLEAN_UP_TIME_US
* microseconds to do any clean-up actions on the RADIO peripheral and stop using it.
* For this reason, the arbiter must call this function NRF_RAAL_MAX_CLEAN_UP_TIME_US microseconds
* before timeslot is finished.
*
* If RAAL is in the continuous mode, the next timeslot will be indicated again by
* @p nrf_raal_timeslot_started function.
* If RAAL is in the continuous mode, the next timeslot is indicated again by
* the @p nrf_raal_timeslot_started function.
*
* This method shall not be called if @p nrf_raal_continuous_mode_exit has been called. Radio
* driver shall assume that timeslot has been finished after @p nrf_raal_continuous_mode_exit
* call.
* The radio driver will assume that the timeslot has been finished after
* the @p nrf_raal_continuous_mode_exit call.
*
* @note Because radio driver needs to stop any operation on RADIO peripheral within
* NRF_RAAL_MAX_CLEAN_UP_TIME_US microseconds, this method should be called with high
* @note Because the radio driver must stop any operation on the RADIO peripheral within
* NRF_RAAL_MAX_CLEAN_UP_TIME_US microseconds, this method is to be called with high
* interrupt priority level to avoid unwanted delays.
*
*/
@@ -51,8 +51,8 @@ extern "C" {
/**
* @def NRF_RAAL_MAX_CLEAN_UP_TIME_US
*
* Maximum time within radio driver needs to do any clean-up actions on RADIO peripheral
* and stop using it completely.
* 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
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contains debug helpers for 802.15.4 radio driver for nRF SoC devices.
* @brief Module that contains debug helpers for the 802.15.4 radio driver for the nRF SoC devices.
*
*/
@@ -29,7 +29,7 @@
*/
/**
* @brief This module contains debug helpers for 802.15.4 radio driver for nRF SoC devices.
* @brief Module that contains debug helpers for the 802.15.4 radio driver for the nRF SoC devices.
*
*/
@@ -788,6 +788,8 @@ void nrf_raal_continuous_mode_exit(void)
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);
@@ -29,7 +29,8 @@
*/
/**
* @brief This module defines Radio Arbiter Abstraction Layer interface.
* @brief Module that defines the Radio Arbiter Abstraction Layer interface
* using Timeslot API provided by SoftDevice.
*
*/
@@ -45,7 +46,7 @@
extern "C" {
#endif
/** @brief RAAL Softdevice default parameters. */
/** @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( \
@@ -66,9 +67,10 @@ extern "C" {
NRF_RAAL_TIMESLOT_DEFAULT_SAFE_MARGIN_CRYSTAL_TICKS)
/**
* @brief Function used to calculate safe margin from LF clock accuracy in ppm unit.
* @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 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( \
@@ -80,46 +82,50 @@ extern "C" {
typedef struct
{
/**
* @brief Timeslot length requested by the module in microseconds.
* @brief Timeslot length requested by the module, in microseconds.
*/
uint32_t timeslot_length;
/**
* @brief Longest acceptable delay until the start of the requested timeslot in microseconds.
* @brief The longest acceptable delay until the start of the requested timeslot,
* in microseconds.
*/
uint32_t timeslot_timeout;
/**
* @brief Maximum single timeslot length created by extension processing in microseconds.
* @brief The maximum single timeslot length created by the extension processing,
* in microseconds.
*/
uint32_t timeslot_max_length;
/**
* @brief Maximum number of iteration of dividing timeslot_length by factor of 2 performed by arbiter.
* @brief The maximum number of iteration of dividing timeslot_length by factor of 2 performed
* by the arbiter.
*/
uint16_t timeslot_alloc_iters;
/**
* @brief Safe margin before timeslot is finished and nrf_raal_timeslot_ended should be called in microseconds.
* @ref nrf_raal_softdevice_safe_margin_calc can be used to calculate proper value based on clock accuracy.
* This value can also be selected experimentally.
* @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 Clock accuracy in ppm unit.
* @brief The clock accuracy in ppm unit.
*/
uint16_t lf_clk_accuracy_ppm;
} nrf_raal_softdevice_cfg_t;
/**
* @brief Function used to inform RAAL client about Softdevice's SoC events.
* @brief Informs the RAAL client about the SoftDevice SoC events.
*
*/
void nrf_raal_softdevice_soc_evt_handler(uint32_t evt_id);
/**
* @brief Function used to set non-default parameters of RAAL.
* @brief Sets non-default parameters of RAAL.
*
*/
void nrf_raal_softdevice_config(const nrf_raal_softdevice_cfg_t * p_cfg);
@@ -172,14 +172,19 @@ static inline void handle_timer(void)
}
/**
* @brief Remove timer from the queue
* @brief Remove a timer from the queue.
*
* @param [inout] p_timer Pointer to timer to remove 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)
static bool timer_remove(nrf_802154_timer_t * p_timer, bool * p_was_running)
{
assert(p_timer != NULL);
@@ -251,10 +256,13 @@ static bool timer_remove(nrf_802154_timer_t * p_timer)
}
}
bool was_running = false;
// Write to the pointer next on removal to ensure that node removal is detected by
// lower pritority context in case it was going to be used.
// lower priority context in case it was going to be used.
if (p_cur != NULL)
{
was_running = true;
uint32_t temp;
do
@@ -266,6 +274,11 @@ static bool timer_remove(nrf_802154_timer_t * p_timer)
while (__STREXW(temp, (uint32_t *)&p_cur->p_next));
}
if (p_was_running != NULL)
{
*p_was_running = was_running;
}
return (timer_start || timer_stop);
}
@@ -332,7 +345,7 @@ void nrf_802154_timer_sched_add(nrf_802154_timer_t * p_timer, bool round_up)
p_timer->dt += nrf_802154_lp_timer_granularity_get() - 1;
}
if (timer_remove(p_timer))
if (timer_remove(p_timer, NULL))
{
handle_timer();
}
@@ -396,9 +409,9 @@ void nrf_802154_timer_sched_add(nrf_802154_timer_t * p_timer, bool round_up)
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_TSCH_ADD);
}
void nrf_802154_timer_sched_remove(nrf_802154_timer_t * p_timer)
void nrf_802154_timer_sched_remove(nrf_802154_timer_t * p_timer, bool * p_was_running)
{
if (timer_remove(p_timer))
if (timer_remove(p_timer, p_was_running))
{
handle_timer();
}
@@ -443,9 +456,11 @@ void nrf_802154_lp_timer_fired(void)
nrf_802154_timer_callback_t callback = p_timer->callback;
void * p_context = p_timer->p_context;
(void)timer_remove(p_timer);
bool was_running;
if (callback != NULL)
(void)timer_remove(p_timer, &was_running);
if (was_running && (callback != NULL))
{
callback(p_context);
}
@@ -29,16 +29,14 @@
*/
/**
* @brief This module provides timer scheduling functionality for the 802.15.4 driver.
* @brief Module that provides the timer scheduling functionality for the 802.15.4 driver.
*
* Timer module should be used to implement strict timing features specified in IEEE 802.15.4 like:
* * CSL,
* * Timing out waiting for ACK frames,
* * CSMA/CA,
* * Inter-frame spacing: SIFS, LIFS (note that AIFS is implemented without using timer module).
* Use the timer scheduler module to implement the strict timing features specified in the IEEE 802.15.4, like:
* * CSL
* * Timing out when waiting for ACK frames
* * CSMA/CA
* * Inter-frame spacing: SIFS, LIFS (AIFS is implemented without using the timer module)
*
* @note Current implementation supports only single one-shot timer. It may be extended to support
* timer scheduling and repetitive timers if needed.
*/
#ifndef NRF_802154_TIMER_SCHED_H_
@@ -55,64 +53,64 @@ extern "C" {
* @defgroup nrf_802154_timer_sched Timer Scheduler module for the 802.15.4 driver
* @{
* @ingroup nrf_802154_timer_sched
* @brief Timer Scheduler module for the 802.15.4 driver.
* @brief The Timer Scheduler module for the 802.15.4 driver.
*
*/
/**
* @brief Type of function called when timer fires.
* @brief Type of function called when the timer expires.
*
* @param[inout] p_context Pointer to user-defined memory location. May be NULL.
* @param[inout] p_context Pointer to user-defined memory location. Can be NULL.
*/
typedef void (* nrf_802154_timer_callback_t)(void * p_context);
/**
* @brief Type for driver instance.
* @brief Type for the driver instance.
*/
typedef struct nrf_802154_timer_s nrf_802154_timer_t;
/**
* @brief Structure containing timer data used by timer module.
* @brief Structure containing timer data used by the timer module.
*/
struct nrf_802154_timer_s
{
uint32_t t0; ///< Base time of the timer [us]
uint32_t dt; ///< Timer expiration delta from @p t0 [us]
nrf_802154_timer_callback_t callback; ///< Callback function called when timer expires
void * p_context; ///< User-defined context passed to callback function
nrf_802154_timer_t * p_next; ///< A pointer to the next running timer
uint32_t t0; ///< Base time of the timer, in microseconds.
uint32_t dt; ///< Timer expiration delta from @p t0, in microseconds.
nrf_802154_timer_callback_t callback; ///< Callback function called when timer expires.
void * p_context; ///< User-defined context passed to the callback function.
nrf_802154_timer_t * p_next; ///< Pointer to the next running timer.
};
/**
* @brief Initialize the timer scheduler.
* @brief Initializes the timer scheduler.
*/
void nrf_802154_timer_sched_init(void);
/**
* @brief Deinitialize the timer scheduler.
* @brief Deinitializes the timer scheduler.
*/
void nrf_802154_timer_sched_deinit(void);
/**
* @brief Get current time.
* @brief Gets the current time.
*
* This function is useful to set base time in @sa nrf_802154_timer_t structure.
* This function can be used to set the base time in the @ref nrf_802154_timer_t structure.
*
* @return Current time in microseconds [us].
* @returns Current time in microseconds [us].
*/
uint32_t nrf_802154_timer_sched_time_get(void);
/**
* @brief Get granularity of the timer that runs the timer scheduler.
* @brief Gets the granularity of the timer that runs the timer scheduler.
*
* @return Granularity of the timer in microseconds [us].
* @returns Granularity of the timer, in microseconds [us].
*/
uint32_t nrf_802154_timer_sched_granularity_get(void);
/**
* @brief Check if given time is in future.
* @brief Checks if the given time is in the future.
*
* @param[in] now Current time. @sa nrf_802154_timer_sched_time_get()
* @param[in] now Current time. @ref nrf_802154_timer_sched_time_get().
* @param[in] t0 Base of time compared with @p now.
* @param[in] dt Time delta from @p t0 compared with @p now.
*
@@ -122,39 +120,44 @@ uint32_t nrf_802154_timer_sched_granularity_get(void);
bool nrf_802154_timer_sched_time_is_in_future(uint32_t now, uint32_t t0, uint32_t dt);
/**
* @brief Get timer time remaining to expiration.
* @brief Gets timer time that remains to expiration.
*
* @param[in] p_timer Pointer to the timer to check remaining time.
* @param[in] p_timer Pointer to the timer to check the remaining time.
*
* @returns Remaining time in microseconds, or zero if the timer has already expired.
*
* @retval remaining time [us] or 0 if timer has already expired.
*/
uint32_t nrf_802154_timer_sched_remaining_time_get(const nrf_802154_timer_t * p_timer);
/**
* @brief Start given timer and add it to the scheduler.
* @brief Starts the given timer and adds it to the scheduler.
*
* @note Fields t0, dt, callback and p_context should be filled in @p p_timer prior to calling this
* function; callback field cannot be NULL.
* @note Fields @c t0, @c dt, @c callback and @c p_context must be filled in @p p_timer before
* calling this function. The @c callback field cannot be NULL.
*
* @note Due to timer granularity the callback function cannot be called exactly at specified time.
* Use @p round_up to specify if given timer should be expired before or after time given in
* the @p p_timer structure. The dt field of the @p p_timer is updated with the rounded up value.
* @note Due to the timer granularity, the callback function cannot be called exactly
* at the specified time. Use @p round_up to specify if the given timer should expire before
* or after the time given in the @p p_timer structure. The @c dt field of the @p p_timer
* is updated with the rounded-up value.
*
* @param[inout] p_timer Pointer to the timer to start and add to the scheduler.
* @param[in] round_up True if timer should expire after specified time, false if it should
* expire before.
* @param[inout] p_timer Pointer to the timer to be started and added to the scheduler.
* @param[in] round_up True if the timer is to expire after the specified time.
* False if it is to expire before the specified time.
*/
void nrf_802154_timer_sched_add(nrf_802154_timer_t * p_timer, bool round_up);
/**
* @brief Stop given timer and remove it from the scheduler.
* @brief Stops the given timer and removes it from the scheduler.
*
* @param[inout] p_timer Pointer to the timer to stop and remove from the scheduler.
* @param[in,out] p_timer Pointer to the timer to be stopped and removed
* from the scheduler.
* @param[out] p_was_running Inform a caller if the timer was running.
* Pass NULL if irrelevant.
*/
void nrf_802154_timer_sched_remove(nrf_802154_timer_t * p_timer);
void nrf_802154_timer_sched_remove(nrf_802154_timer_t * p_timer, bool * p_was_running);
/**
* @brief Check if given timer is already scheduled.
* @brief Checks if the given timer is already scheduled.
*
* @param[in] p_timer Pointer to the timer to check.
*