diff --git a/drivers/nrf_802154/CMakeLists.txt b/drivers/nrf_802154/CMakeLists.txt index 1b334a6c..4a887071 100644 --- a/drivers/nrf_802154/CMakeLists.txt +++ b/drivers/nrf_802154/CMakeLists.txt @@ -41,7 +41,3 @@ add_subdirectory(driver) add_subdirectory(sl) add_subdirectory(serialization) - -if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/internal/CMakeLists.txt) - add_subdirectory(internal) -endif () diff --git a/drivers/nrf_802154/common/include/nrf_802154.h b/drivers/nrf_802154/common/include/nrf_802154.h index fae254be..419f1758 100644 --- a/drivers/nrf_802154/common/include/nrf_802154.h +++ b/drivers/nrf_802154/common/include/nrf_802154.h @@ -415,7 +415,12 @@ bool nrf_802154_receive(void); * If the requested reception time is in the past, the function returns false and does not * schedule reception. * - * A scheduled reception can be cancelled by a call to @ref nrf_802154_receive_at_cancel. + * The reception ends after the configured timeout has elapsed. This event is notified to the + * higher layer through the @ref nrf_802154_receive_failed notification with + * @ref NRF_802154_RX_ERROR_DELAYED_TIMEOUT status code. + * + * A scheduled reception can be cancelled by a call to @ref nrf_802154_receive_at_cancel or + * @ref nrf_802154_receive_at_scheduled_cancel. * * @note The identifier @p id must be unique. It must not have the same value as identifiers * of other delayed timeslots active at the moment, so that it can be mapped unambiguously @@ -427,7 +432,8 @@ bool nrf_802154_receive(void); * @param[in] channel Radio channel on which the frame is to be received. * @param[in] id Identifier of the scheduled reception window. If the reception has been * scheduled successfully, the value of this parameter can be used in - * @ref nrf_802154_receive_at_cancel to cancel it. + * @ref nrf_802154_receive_at_cancel or + * @ref nrf_802154_receive_at_scheduled_cancel to cancel it. * * @retval true The reception procedure was scheduled. * @retval false The driver could not schedule the reception procedure. @@ -453,6 +459,35 @@ bool nrf_802154_receive_at(uint64_t rx_time, */ bool nrf_802154_receive_at_cancel(uint32_t id); +/** + * @brief Cancels a delayed reception scheduled by a call to @ref nrf_802154_receive_at. + * + * If the receive window has been scheduled but has not started yet, this function prevents + * entering the receive window. If the receive window has been scheduled and has already started, + * the receive window is not affected and will continue until its scheduled timeout. + * + * The function also returns success when no window with given ID is scheduled and is not currently + * ongoing. + * + * @note This function differs from @ref nrf_802154_receive_at_cancel in two aspects: + * 1. This function can only cancel receive windows that are scheduled, but haven't started yet. + * If the receive window has already started, the cancel will end with failure and the + * receive window will last for the planned duration, ending with + * @ref nrf_802154_receive_failed notification with @ref NRF_802154_RX_ERROR_DELAYED_TIMEOUT + * status. + * 2. If there are no scheduled and ongoing receive windows matching the given ID, + * the function ends with a success. + * + * @param[in] id Identifier of the delayed reception window to be cancelled. If the provided + * value does not refer to any scheduled or active receive window, the function + * returns true. + * + * @retval true The delayed reception was scheduled and successfully cancelled or the + * receive window was not scheduled at all. + * @retval false The scheduled window is currently ongoing. + */ +bool nrf_802154_receive_at_scheduled_cancel(uint32_t id); + /** * @brief Changes the radio state to @ref RADIO_STATE_TX. * diff --git a/drivers/nrf_802154/common/include/nrf_802154_config.h b/drivers/nrf_802154/common/include/nrf_802154_config.h index 45c37a0b..994afa08 100644 --- a/drivers/nrf_802154/common/include/nrf_802154_config.h +++ b/drivers/nrf_802154/common/include/nrf_802154_config.h @@ -97,6 +97,23 @@ extern "C" { #define NRF_802154_CCA_CORR_LIMIT_DEFAULT 0x02 #endif +/** + * @def NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US + * + * Additional time in microseconds that delays triggering of @c TXEN after the + * @c CCAIDLE event occurred. Default value for most use-cases is @c 0, + * In this scenario, the short between the @c CCAIDLE event and the + * @c TXEN task is used. If this value is non-zero, the short is not used. + * The triggering of @c TXEN occurs through (D)PPI and TIMER. + * A non-zero value may be necessary to ensure enough switching time for + * use with some Front-End Modules. + * + * This option is supported for the nRF53 Series and the nRF54L Series only. + */ +#ifndef NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US +#define NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US 0U +#endif + /** * @def NRF_802154_INTERNAL_RADIO_IRQ_HANDLING * diff --git a/drivers/nrf_802154/driver/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c b/drivers/nrf_802154/driver/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c index 515d0b19..9f7131b3 100644 --- a/drivers/nrf_802154/driver/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c +++ b/drivers/nrf_802154/driver/src/mac_features/ack_generator/nrf_802154_enh_ack_generator.c @@ -287,8 +287,8 @@ static uint8_t security_key_id_set(const nrf_802154_frame_parser_data_t * p_fram { const uint8_t * p_frame_key_id = nrf_802154_frame_parser_key_id_get(p_frame_data); uint8_t * p_ack_key_id = (uint8_t *)nrf_802154_frame_parser_key_id_get(p_ack_data); - uint8_t key_id_size = key_id_size_get(nrf_802154_frame_parser_sec_ctrl_key_id_mode_get( - p_ack_data)); + uint8_t key_id_size = + key_id_size_get(nrf_802154_frame_parser_sec_ctrl_key_id_mode_get(p_ack_data)); if ((p_ack_key_id != NULL) && (p_frame_key_id != NULL)) { @@ -416,35 +416,6 @@ static void ie_header_set(const uint8_t * p_ie_data, #endif } -static uint8_t ie_header_terminate(const uint8_t * p_ie_data, - uint8_t ie_data_len, - nrf_802154_frame_parser_data_t * p_ack_data) -{ - if (p_ie_data == NULL) - { - // No IEs to terminate. - return 0U; - } - - if ((nrf_802154_frame_parser_security_enabled_bit_is_set(p_ack_data) == false) || - (nrf_802154_frame_parser_sec_ctrl_sec_lvl_get(p_ack_data) == SECURITY_LEVEL_NONE)) - { - // This code assumes that neither regular frame payload nor Payload IEs can be set by the - // driver. Therefore without security, the Ack has no payload, so termination is not necessary. - return 0U; - } - - uint8_t * p_ack_ie = (uint8_t *)p_ack_data->p_frame + p_ack_data->helper.aux_sec_hdr_end_offset; - uint8_t ie_hdr_term[IE_HEADER_SIZE]; - - NRF_802154_ASSERT(p_ack_ie != NULL); - - host_16_to_little((IE_HT2) << IE_HEADER_ELEMENT_ID_OFFSET, ie_hdr_term); - - memcpy(p_ack_ie + ie_data_len, ie_hdr_term, sizeof(ie_hdr_term)); - return sizeof(ie_hdr_term); -} - /*************************************************************************************************** * @section Authentication and encryption transformation **************************************************************************************************/ @@ -543,8 +514,8 @@ static void ie_process(const nrf_802154_frame_parser_data_t * p_frame_data) ie_header_set(mp_ie_data, m_ie_data_len, &m_ack_data); m_ack[PHR_OFFSET] += m_ie_data_len; - // Terminate the IE header if needed. - m_ack[PHR_OFFSET] += ie_header_terminate(mp_ie_data, m_ie_data_len, &m_ack_data) + FCS_SIZE; + // Add space for the FCS field. + m_ack[PHR_OFFSET] += FCS_SIZE; bool result = nrf_802154_frame_parser_valid_data_extend(&m_ack_data, m_ack[PHR_OFFSET] + PHR_SIZE, diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c index a74f80dd..fa0d2ce7 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.c @@ -795,9 +795,10 @@ bool nrf_802154_delayed_trx_transmit(uint8_t * p p_dly_tx_data->tx.p_data = p_data; p_dly_tx_data->tx.params.frame_props = p_metadata->frame_props; - (void)nrf_802154_tx_power_convert_metadata_to_tx_power_split(p_metadata->channel, - p_metadata->tx_power, - &p_dly_tx_data->tx.params.tx_power); + (void)nrf_802154_tx_power_convert_metadata_to_tx_power_split( + p_metadata->channel, + p_metadata->tx_power, + &p_dly_tx_data->tx.params.tx_power); p_dly_tx_data->tx.params.cca = p_metadata->cca; p_dly_tx_data->tx.params.immediate = true; p_dly_tx_data->tx.params.extra_cca_attempts = p_metadata->extra_cca_attempts; @@ -918,6 +919,36 @@ bool nrf_802154_delayed_trx_receive_cancel(uint32_t id) return stopped; } +bool nrf_802154_delayed_trx_receive_scheduled_cancel(uint32_t id) +{ + dly_op_data_t * p_dly_op_data = dly_rx_data_by_id_search(id); + + if (p_dly_op_data == NULL) + { + // Delayed receive window with provided ID could not be found. + return true; + } + + bool result = nrf_802154_rsch_delayed_timeslot_cancel(id, false); + + if (!result) + { + result = + nrf_802154_sl_atomic_load_u8((uint8_t *)&p_dly_op_data->state) == + DELAYED_TRX_OP_STATE_STOPPED; + } + + if (result) + { + p_dly_op_data->id = NRF_802154_RESERVED_INVALID_ID; + + nrf_802154_sl_atomic_store_u8((uint8_t *)&p_dly_op_data->state, + DELAYED_TRX_OP_STATE_STOPPED); + } + + return result; +} + bool nrf_802154_delayed_trx_abort(nrf_802154_term_t term_lvl, req_originator_t req_orig) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.h b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.h index 514465c8..7103e1c4 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.h +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_delayed_trx.h @@ -137,6 +137,22 @@ bool nrf_802154_delayed_trx_receive(uint64_t rx_time, */ bool nrf_802154_delayed_trx_receive_cancel(uint32_t id); +/** + * @brief Cancels a scheduled reception scheduled by a call to @ref nrf_802154_delayed_trx_receive. + * + * If the receive window is currently ongoing, it will not be affected and a timeout event will + * be notified at scheduled time. + * + * @param[in] id Identifier of the delayed reception window to be cancelled. If the provided + * value does not refer to any scheduled or active receive window, the function + * returns true. + * + * @retval true Successfully cancelled a scheduled transmission or no window + * with given ID is scheduled. + * @retval false The receive window is currently ongoing. + */ +bool nrf_802154_delayed_trx_receive_scheduled_cancel(uint32_t id); + /** * @brief Aborts an ongoing delayed reception procedure. * diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_frame_parser.c b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_frame_parser.c index 984d04c8..ef3039e2 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_frame_parser.c +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_frame_parser.c @@ -305,6 +305,7 @@ static bool sec_ctrl_parse(nrf_802154_frame_parser_data_t * p_parser_data) if (nrf_802154_frame_parser_security_enabled_bit_is_set(p_parser_data) == false) { p_parser_data->helper.aux_sec_hdr_end_offset = offset; + p_parser_data->helper.mic_size = 0; return true; } @@ -515,9 +516,10 @@ bool nrf_802154_frame_parser_data_init(const uint8_t * p_frame, return parse_state_advance(p_parser_data, requested_parse_level); } -bool nrf_802154_frame_parser_valid_data_extend(nrf_802154_frame_parser_data_t * p_parser_data, - uint8_t valid_data_len, - nrf_802154_frame_parser_level_t requested_parse_level) +bool nrf_802154_frame_parser_valid_data_extend( + nrf_802154_frame_parser_data_t * p_parser_data, + uint8_t valid_data_len, + nrf_802154_frame_parser_level_t requested_parse_level) { if (valid_data_len > p_parser_data->valid_data_len) { diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_frame_parser.h b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_frame_parser.h index f5dc3b29..f6016a2b 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_frame_parser.h +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_frame_parser.h @@ -209,9 +209,10 @@ bool nrf_802154_frame_parser_data_init(const uint8_t * p_frame, * @retval true The parsing succeeded and requested parse level was achieved. * @retval false The parsing failed or requested parse level could not be achieved. */ -bool nrf_802154_frame_parser_valid_data_extend(nrf_802154_frame_parser_data_t * p_parser_data, - uint8_t valid_data_len, - nrf_802154_frame_parser_level_t requested_parse_level); +bool nrf_802154_frame_parser_valid_data_extend( + nrf_802154_frame_parser_data_t * p_parser_data, + uint8_t valid_data_len, + nrf_802154_frame_parser_level_t requested_parse_level); /** * @brief Gets current parse level of the provided parser data. @@ -1015,6 +1016,19 @@ static inline const uint8_t * nrf_802154_frame_parser_mfr_get( return &p_parser_data->p_frame[offset]; } +/** + * @brief Gets the length of the MIC field. + * + * @param[in] p_parser_data Pointer to a frame parser data. + * + * @returns Length of the MIC field. + */ +static inline uint8_t nrf_802154_frame_parser_mic_size_get( + const nrf_802154_frame_parser_data_t * p_parser_data) +{ + return p_parser_data->helper.mic_size; +} + /** * @brief Gets the length of the MAC payload. * @@ -1025,8 +1039,9 @@ static inline const uint8_t * nrf_802154_frame_parser_mfr_get( static inline uint8_t nrf_802154_frame_parser_mac_payload_length_get( const nrf_802154_frame_parser_data_t * p_parser_data) { + uint8_t mic_len = nrf_802154_frame_parser_mic_size_get(p_parser_data); uint8_t payload_start = nrf_802154_frame_parser_mac_payload_offset_get(p_parser_data); - uint8_t payload_end = nrf_802154_frame_parser_mfr_offset_get(p_parser_data); + uint8_t payload_end = nrf_802154_frame_parser_mfr_offset_get(p_parser_data) - mic_len; return payload_end - payload_start; } @@ -1052,19 +1067,6 @@ static inline uint8_t nrf_802154_frame_parser_mac_header_length_get( return mhr_end - mhr_start; } -/** - * @brief Gets the length of the MIC field. - * - * @param[in] p_parser_data Pointer to a frame parser data. - * - * @returns Length of the MIC field. - */ -static inline uint8_t nrf_802154_frame_parser_mic_size_get( - const nrf_802154_frame_parser_data_t * p_parser_data) -{ - return p_parser_data->helper.mic_size; -} - /** * @brief Gets the end offset of the destination addressing section. * diff --git a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c index b16c4b4c..df5219a9 100644 --- a/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c +++ b/drivers/nrf_802154/driver/src/mac_features/nrf_802154_ie_writer.c @@ -382,8 +382,8 @@ static void cst_ie_write_reset(void) #endif // NRF_802154_DELAYED_TRX_ENABLED static uint8_t * mp_lm_rssi_addr; ///< Cached Link Metrics information element RSSI field address -static uint8_t * mp_lm_margin_addr; ///< Cached Link Metrics information element link margin field address -static uint8_t * mp_lm_lqi_addr; ///< Cached Link Metrics information element LQI field address +static uint8_t * mp_lm_margin_addr; ///< Cached Link Metrics information element link margin field address +static uint8_t * mp_lm_lqi_addr; ///< Cached Link Metrics information element LQI field address static uint8_t rssi_scale(int8_t rssi) { diff --git a/drivers/nrf_802154/driver/src/nrf_802154.c b/drivers/nrf_802154/driver/src/nrf_802154.c index 97f4fa1f..0d7ccbce 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154.c +++ b/drivers/nrf_802154/driver/src/nrf_802154.c @@ -561,6 +561,18 @@ bool nrf_802154_receive_at_cancel(uint32_t id) return result; } +bool nrf_802154_receive_at_scheduled_cancel(uint32_t id) +{ + bool result; + + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_LOW); + + result = nrf_802154_request_receive_at_scheduled_cancel(id); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); + return result; +} + #endif // NRF_802154_DELAYED_TRX_ENABLED bool nrf_802154_energy_detection(uint32_t time_us) diff --git a/drivers/nrf_802154/driver/src/nrf_802154_core.c b/drivers/nrf_802154/driver/src/nrf_802154_core.c index f064cbb7..a5f5f8e7 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_core.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_core.c @@ -2010,6 +2010,11 @@ void nrf_802154_trx_receive_frame_received(void) #if (NRF_802154_FRAME_TIMESTAMP_ENABLED) uint64_t ts = timer_coord_timestamp_get(); + if (ts != NRF_802154_NO_TIMESTAMP) + { + ts -= RX_PHYEND_EVENT_LATENCY_US; + } + nrf_802154_stat_timestamp_write(last_rx_end_timestamp, ts); #endif diff --git a/drivers/nrf_802154/driver/src/nrf_802154_critical_section.c b/drivers/nrf_802154/driver/src/nrf_802154_critical_section.c index b1ef54b6..bf610068 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_critical_section.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_critical_section.c @@ -58,8 +58,8 @@ #define NESTED_CRITICAL_SECTION_ALLOWED_PRIORITY_NONE (-1) -static volatile uint8_t m_nested_critical_section_counter; ///< Counter of nested critical sections -static volatile int8_t m_nested_critical_section_allowed_priority; ///< Indicator if nested critical sections are currently allowed +static volatile uint8_t m_nested_critical_section_counter; ///< Counter of nested critical sections +static volatile int8_t m_nested_critical_section_allowed_priority; ///< Indicator if nested critical sections are currently allowed /*************************************************************************************************** * @section Critical sections management diff --git a/drivers/nrf_802154/driver/src/nrf_802154_debug_gpio.c b/drivers/nrf_802154/driver/src/nrf_802154_debug_gpio.c index 243d3bae..5b0cf0e1 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_debug_gpio.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_debug_gpio.c @@ -56,36 +56,42 @@ static void radio_event_gpio_toggle_init(void) nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_DISABLED); nrf_gpio_cfg_output(PIN_DBG_RADIO_EVT_READY); - nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_END, + nrf_gpiote_task_configure(NRF_GPIOTE, + GPIOTE_DBG_RADIO_EVT_END, PIN_DBG_RADIO_EVT_END, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_DISABLED, + nrf_gpiote_task_configure(NRF_GPIOTE, + GPIOTE_DBG_RADIO_EVT_DISABLED, PIN_DBG_RADIO_EVT_DISABLED, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_configure(GPIOTE_DBG_RADIO_EVT_READY, + nrf_gpiote_task_configure(NRF_GPIOTE, + GPIOTE_DBG_RADIO_EVT_READY, PIN_DBG_RADIO_EVT_READY, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); - nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_END); - nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_DISABLED); - nrf_gpiote_task_enable(GPIOTE_DBG_RADIO_EVT_READY); + nrf_gpiote_task_enable(NRF_GPIOTE, GPIOTE_DBG_RADIO_EVT_END); + nrf_gpiote_task_enable(NRF_GPIOTE, GPIOTE_DBG_RADIO_EVT_DISABLED); + nrf_gpiote_task_enable(NRF_GPIOTE, GPIOTE_DBG_RADIO_EVT_READY); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_END, + nrf_ppi_channel_endpoint_setup(NRF_PPI, + (nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_END, (uint32_t)&NRF_RADIO->EVENTS_END, - nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_0)); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_DISABLED, + nrf_gpiote_task_address_get(NRF_GPIOTE, NRF_GPIOTE_TASK_OUT_0)); + nrf_ppi_channel_endpoint_setup(NRF_PPI, + (nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_DISABLED, (uint32_t)&NRF_RADIO->EVENTS_DISABLED, - nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_1)); - nrf_ppi_channel_endpoint_setup((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_READY, - (uint32_t)&NRF_RADIO->EVENTS_READY, - nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_2)); + nrf_gpiote_task_address_get(NRF_GPIOTE, NRF_GPIOTE_TASK_OUT_1)); + nrf_ppi_channel_endpoint_setup(NRF_PPI, + (nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_READY, + (uint32_t)&NRF_RADIO->EVENTS_RXREADY, + nrf_gpiote_task_address_get(NRF_GPIOTE, NRF_GPIOTE_TASK_OUT_2)); - nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_END); - nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_DISABLED); - nrf_ppi_channel_enable((nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_READY); + nrf_ppi_channel_enable(NRF_PPI, (nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_END); + nrf_ppi_channel_enable(NRF_PPI, (nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_DISABLED); + nrf_ppi_channel_enable(NRF_PPI, (nrf_ppi_channel_t)PPI_DBG_RADIO_EVT_READY); } /** diff --git a/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c b/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c index 9ee16413..e0226e16 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_encrypt.c @@ -101,14 +101,13 @@ static bool a_data_and_m_data_prepare( // It is assumed that the provided frame has a placeholder of appropriate length for MIC // at the end. The algorithm inputs should only contain MAC payload, so the MIC placeholder // of the below length should be removed - uint8_t mic_len = nrf_802154_frame_parser_mic_size_get(p_frame_data); uint8_t * p_mac_hdr = (uint8_t *)nrf_802154_frame_parser_psdu_get(p_frame_data); uint8_t mac_hdr_len = nrf_802154_frame_parser_mac_header_length_get(p_frame_data) + open_payload_len; uint8_t * p_mac_payload = (uint8_t *)(nrf_802154_frame_parser_mac_payload_get(p_frame_data) + open_payload_len); uint8_t mac_payload_len = - nrf_802154_frame_parser_mac_payload_length_get(p_frame_data) - mic_len - open_payload_len; + nrf_802154_frame_parser_mac_payload_length_get(p_frame_data) - open_payload_len; switch (nrf_802154_frame_parser_sec_ctrl_sec_lvl_get(p_frame_data)) { diff --git a/drivers/nrf_802154/driver/src/nrf_802154_peripherals.h b/drivers/nrf_802154/driver/src/nrf_802154_peripherals.h index 6c61b803..3ed6d5d2 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_peripherals.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_peripherals.h @@ -224,7 +224,7 @@ extern "C" { * of an interrupt by the RADIO.EVENTS_SYNC event. * */ -#define NRF_802154_EGU_SYNC_CHANNEL_NO 3 +#define NRF_802154_EGU_SYNC_CHANNEL_NO 3 /** * @def NRF_802154_EGU_SYNC_USED_CHANNELS_MASK @@ -232,14 +232,14 @@ extern "C" { * Mask of EGU channels used by the interrupt generation from the RADIO.EVENTS_SYNC event. * See @ref NRF_802154_EGU_USED_CHANNELS_MASK. */ -#define NRF_802154_EGU_SYNC_USED_CHANNELS_MASK (1U << NRF_802154_EGU_SYNC_CHANNEL_NO) +#define NRF_802154_EGU_SYNC_USED_CHANNELS_MASK (1U << NRF_802154_EGU_SYNC_CHANNEL_NO) /** * @def NRF_802154_EGU_RAMP_UP_CHANNEL_NO * * The channel number of the @ref NRF_802154_EGU_INSTANCE used for triggering the ramp-up of the RADIO. */ -#define NRF_802154_EGU_RAMP_UP_CHANNEL_NO 15 +#define NRF_802154_EGU_RAMP_UP_CHANNEL_NO 15 /** * @def NRF_802154_EGU_RAMP_UP_USED_CHANNELS_MASK @@ -247,23 +247,31 @@ extern "C" { * Mask of EGU channels used for triggering the ramp-up of the RADIO. * See @ref NRF_802154_EGU_USED_CHANNELS_MASK. */ -#define NRF_802154_EGU_RAMP_UP_USED_CHANNELS_MASK (1U << NRF_802154_EGU_RAMP_UP_CHANNEL_NO) +#define NRF_802154_EGU_RAMP_UP_USED_CHANNELS_MASK (1U << NRF_802154_EGU_RAMP_UP_CHANNEL_NO) /** * @def NRF_802154_EGU_RAMP_UP_EVENT * * The EGU event used by the driver to trigger radio ramp-up. */ -#define NRF_802154_EGU_RAMP_UP_EVENT NRFX_CONCAT_2(NRF_EGU_EVENT_TRIGGERED, \ - NRF_802154_EGU_RAMP_UP_CHANNEL_NO) +#define NRF_802154_EGU_RAMP_UP_EVENT NRFX_CONCAT_2(NRF_EGU_EVENT_TRIGGERED, \ + NRF_802154_EGU_RAMP_UP_CHANNEL_NO) /** * @def NRF_802154_EGU_RAMP_UP_TASK * * The EGU task used by the driver to trigger radio ramp-up. */ -#define NRF_802154_EGU_RAMP_UP_TASK NRFX_CONCAT_2(NRF_EGU_TASK_TRIGGER, \ - NRF_802154_EGU_RAMP_UP_CHANNEL_NO) +#define NRF_802154_EGU_RAMP_UP_TASK NRFX_CONCAT_2(NRF_EGU_TASK_TRIGGER, \ + NRF_802154_EGU_RAMP_UP_CHANNEL_NO) + +#ifndef NRF_802154_EGU_TIMER_START_USED_CHANNELS_MASK +#define NRF_802154_EGU_TIMER_START_USED_CHANNELS_MASK 0U +#endif + +#ifndef NRF_802154_EGU_TIMER_START2_USED_CHANNELS_MASK +#define NRF_802154_EGU_TIMER_START2_USED_CHANNELS_MASK 0U +#endif /** * @def NRF_802154_EGU_USED_CHANNELS_MASK @@ -276,6 +284,8 @@ extern "C" { NRF_802154_EGU_REQUEST_USED_CHANNELS_MASK | \ NRF_802154_EGU_SYNC_USED_CHANNELS_MASK | \ NRF_802154_EGU_RAMP_UP_USED_CHANNELS_MASK | \ + NRF_802154_EGU_TIMER_START_USED_CHANNELS_MASK | \ + NRF_802154_EGU_TIMER_START2_USED_CHANNELS_MASK | \ NRF_802154_SL_EGU_USED_CHANNELS_MASK) #ifdef __cplusplus diff --git a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_alloc.c b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_alloc.c index c869a749..d71771ec 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_alloc.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_alloc.c @@ -62,7 +62,7 @@ #endif const uint32_t g_nrf_802154_used_nrf_ppi_channels = NRF_802154_PPI_CH_USED_MSK; -const uint32_t g_nrf_802154_used_nrf_ppi_groups = NRF_802154_PPI_GR_USED_MSK; +const uint32_t g_nrf_802154_used_nrf_ppi_groups = NRF_802154_PPI_GR_USED_MSK; #if NRF_802154_VERIFY_PERIPHS_ALLOC_AGAINST_MPSL diff --git a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf52.h b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf52.h index 562b88bb..3909d9a7 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf52.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf52.h @@ -152,28 +152,13 @@ extern "C" { #define NRF_802154_PPI_EGU_TO_TIMER_START 8U #endif -/** - * @def NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR - * - * The PPI channel that connects RADIO_CRCERROR event to TIMER_CLEAR task. - * - * @note This option is used by the core module regardless of the driver configuration. - * The peripheral is shared with @ref NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE - * and @ref NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN. - * - */ -#ifndef NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR -#define NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR 9U -#endif - /** * @def NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE * * The PPI channel that connects RADIO_CCAIDLE event to the GPIOTE tasks used by the Frontend. * * @note This option is used by the core module regardless of the driver configuration. - * The peripheral is shared with @ref NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR - * and @ref NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN. + * The peripheral is shared with @ref NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN. * */ #ifndef NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE @@ -186,8 +171,7 @@ extern "C" { * The PPI channel that connects TIMER_COMPARE event to RADIO_TXEN task. * * @note This option is used by the core module regardless of the driver configuration. - * The peripheral is shared with @ref NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR - * and @ref NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE. + * The peripheral is shared with @ref NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE. * */ #ifndef NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN @@ -262,7 +246,6 @@ extern "C" { (1 << NRF_802154_PPI_RADIO_RAMP_UP_TRIGG) | \ (1 << NRF_802154_PPI_EGU_TO_RADIO_RAMP_UP) | \ (1 << NRF_802154_PPI_EGU_TO_TIMER_START) | \ - (1 << NRF_802154_PPI_RADIO_CRCERROR_TO_TIMER_CLEAR) | \ (1 << NRF_802154_PPI_RADIO_CCAIDLE_TO_FEM_GPIOTE) | \ (1 << NRF_802154_PPI_TIMER_COMPARE_TO_RADIO_TXEN) | \ (1 << NRF_802154_PPI_RADIO_CCABUSY_TO_RADIO_CCASTART) | \ diff --git a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf53.h b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf53.h index a656d77a..16bd93c0 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf53.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf53.h @@ -91,6 +91,32 @@ extern "C" { #define NRF_802154_EGU_USED_MASK (1 << NRF_802154_EGU_INSTANCE_NO) #endif +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) || defined(__DOXYGEN__) + +/** + * @def NRF_802154_EGU_TIMER_START_CHANNEL_NO + * + * The channel number of the @ref NRF_802154_EGU_INSTANCE used for starting the TIMER. + * Used only when @ref NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US is non-zero. + */ +#define NRF_802154_EGU_TIMER_START_CHANNEL_NO 14 + +#define NRF_802154_EGU_TIMER_START_USED_CHANNELS_MASK \ + (1U << NRF_802154_EGU_TIMER_START_CHANNEL_NO) + +/** + * @def NRF_802154_EGU_TIMER_START2_CHANNEL_NO + * + * The channel number of the @ref NRF_802154_EGU_INSTANCE used for starting the TIMER (second source). + * Used only when @ref NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US is non-zero. + */ +#define NRF_802154_EGU_TIMER_START2_CHANNEL_NO 13 + +#define NRF_802154_EGU_TIMER_START2_USED_CHANNELS_MASK \ + (1U << NRF_802154_EGU_TIMER_START2_CHANNEL_NO) + +#endif /* (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) || defined(__DOXYGEN__) */ + /** * @def NRF_802154_RTC_INSTANCE_NO * @@ -206,6 +232,40 @@ extern "C" { #define NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC 12U #endif +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) || defined(__DOXYGEN__) +/** + * @def NRF_802154_DPPI_TIMER_START + * + * The DPPI channel that is used to trigger TIMER's START task. + * Used only when @ref NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US is non-zero. + * + */ +#ifndef NRF_802154_DPPI_TIMER_START +#define NRF_802154_DPPI_TIMER_START 16U +#endif + +/** + * @def NRF_802154_DPPI_RADIO_TXEN + * + * The DPPI channel that is used to trigger RADIO's TXEN task + * in the scenario where short CCAIDLE_TXEN is not used. + * Used only when @ref NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US is non-zero. + * + */ +#ifndef NRF_802154_DPPI_RADIO_TXEN +#define NRF_802154_DPPI_RADIO_TXEN 17U +#endif + +#define NRF_802154_DPPI_TIMER_START_MASK (1U << NRF_802154_DPPI_TIMER_START) +#define NRF_802154_DPPI_RADIO_TXEN_MASK (1U << NRF_802154_DPPI_RADIO_TXEN) + +#else + +#define NRF_802154_DPPI_TIMER_START_MASK 0U +#define NRF_802154_DPPI_RADIO_TXEN_MASK 0U + +#endif /* (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) || defined(__DOXYGEN__) */ + /** * @def NRF_802154_DPPI_RADIO_CCAIDLE * @@ -255,6 +315,8 @@ extern "C" { (1UL << NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP) | \ (1UL << NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN) | \ (1UL << NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC) | \ + (NRF_802154_DPPI_TIMER_START_MASK) | \ + (NRF_802154_DPPI_RADIO_TXEN_MASK) | \ (1UL << NRF_802154_DPPI_RADIO_CCAIDLE) | \ (1UL << NRF_802154_DPPI_RADIO_CCABUSY) | \ (1UL << NRF_802154_DPPI_RADIO_HW_TRIGGER) | \ diff --git a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf54l.h b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf54l.h index 441dd5b0..c661a828 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf54l.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_peripherals_nrf54l.h @@ -90,6 +90,32 @@ extern "C" { #define NRF_802154_EGU_USED_MASK (1 << NRF_802154_EGU_INSTANCE_NO) #endif +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) || defined(__DOXYGEN__) + +/** + * @def NRF_802154_EGU_TIMER_START_CHANNEL_NO + * + * The channel number of the @ref NRF_802154_EGU_INSTANCE used for starting the TIMER. + * Used only when @ref NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US is non-zero. + */ +#define NRF_802154_EGU_TIMER_START_CHANNEL_NO 14 + +#define NRF_802154_EGU_TIMER_START_USED_CHANNELS_MASK \ + (1U << NRF_802154_EGU_TIMER_START_CHANNEL_NO) + +/** + * @def NRF_802154_EGU_TIMER_START2_CHANNEL_NO + * + * The channel number of the @ref NRF_802154_EGU_INSTANCE used for starting the TIMER (second source). + * Used only when @ref NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US is non-zero. + */ +#define NRF_802154_EGU_TIMER_START2_CHANNEL_NO 13 + +#define NRF_802154_EGU_TIMER_START2_USED_CHANNELS_MASK \ + (1U << NRF_802154_EGU_TIMER_START2_CHANNEL_NO) + +#endif /* (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) || defined(__DOXYGEN__) */ + /** * @def NRF_802154_CCM_INSTANCE_NO * @@ -108,7 +134,8 @@ extern "C" { * @note This option is used when @ref NRF_802154_ENCRYPTION_ENABLED is set. * */ -#define NRF_802154_CCM_INSTANCE NRFX_CONCAT_2(NRF_CCM, NRF_802154_CCM_INSTANCE_NO) +#define NRF_802154_CCM_INSTANCE NRFX_CONCAT_2(NRF_CCM, \ + NRF_802154_CCM_INSTANCE_NO) /** * @def NRF_802154_RTC_INSTANCE_NO @@ -233,6 +260,40 @@ extern "C" { #define NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC 22U #endif +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) || defined(__DOXYGEN__) +/** + * @def NRF_802154_DPPI_TIMER_START + * + * The DPPI channel that is used to trigger TIMER's START task. + * Used only when @ref NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US is non-zero. + * + */ +#ifndef NRF_802154_DPPI_TIMER_START +#define NRF_802154_DPPI_TIMER_START 21U +#endif + +/** + * @def NRF_802154_DPPI_RADIO_TXEN + * + * The DPPI channel that is used to trigger RADIO's TXEN task + * in the scenario where short CCAIDLE_TXEN is not used. + * Used only when @ref NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US is non-zero. + * + */ +#ifndef NRF_802154_DPPI_RADIO_TXEN +#define NRF_802154_DPPI_RADIO_TXEN 20U +#endif + +#define NRF_802154_DPPI_TIMER_START_MASK (1U << NRF_802154_DPPI_TIMER_START) +#define NRF_802154_DPPI_RADIO_TXEN_MASK (1U << NRF_802154_DPPI_RADIO_TXEN) + +#else + +#define NRF_802154_DPPI_TIMER_START_MASK 0U +#define NRF_802154_DPPI_RADIO_TXEN_MASK 0U + +#endif /* (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) || defined(__DOXYGEN__) */ + /** * @def NRF_802154_DPPI_RADIO_CCAIDLE * @@ -275,6 +336,8 @@ extern "C" { (1UL << NRF_802154_DPPI_EGU_TO_RADIO_RAMP_UP) | \ (1UL << NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN) | \ (1UL << NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC) | \ + (NRF_802154_DPPI_TIMER_START_MASK) | \ + (NRF_802154_DPPI_RADIO_TXEN_MASK) | \ (1UL << NRF_802154_DPPI_RADIO_CCAIDLE) | \ (1UL << NRF_802154_DPPI_RADIO_CCABUSY) | \ (1UL << NRF_802154_DPPI_RADIO_HW_TRIGGER) | \ diff --git a/drivers/nrf_802154/driver/src/nrf_802154_procedures_duration.h b/drivers/nrf_802154/driver/src/nrf_802154_procedures_duration.h index dde6879c..58e28334 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_procedures_duration.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_procedures_duration.h @@ -50,7 +50,17 @@ #define RX_RAMP_UP_TIME 40 // us #define RX_RAMP_DOWN_TIME 0 // us #define MAX_RAMP_DOWN_TIME 6 // us -#define RX_TX_TURNAROUND_TIME 20 // us +#if defined(NRF54L_SERIES) +#define RX_TX_TURNAROUND_TIME_HW 15 // us +#else +#define RX_TX_TURNAROUND_TIME_HW 20 // us +#endif + +#define RX_TX_TURNAROUND_TIME (RX_TX_TURNAROUND_TIME_HW + \ + NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US) + +#define RX_PHYEND_EVENT_LATENCY_US 23 ///< Latency in us between the last bit on air and the PHYEND event. +#define RSSI_SETTLE_TIME_US 15 ///< Time required for RSSI measurements to become valid after signal level change. #define A_CCA_DURATION_SYMBOLS 8 // sym #define A_TURNAROUND_TIME_SYMBOLS 12 // sym diff --git a/drivers/nrf_802154/driver/src/nrf_802154_request.h b/drivers/nrf_802154/driver/src/nrf_802154_request.h index 575dc9f2..609083fb 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_request.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_request.h @@ -255,6 +255,19 @@ bool nrf_802154_request_receive_at(uint64_t rx_time, */ bool nrf_802154_request_receive_at_cancel(uint32_t id); +/** + * @brief Requests a call to @ref nrf_802154_request_receive_at_scheduled_cancel. + * + * @param[in] id Identifier of the delayed reception window to be cancelled. If the provided + * value does not refer to any scheduled or active receive window, the function + * returns true. + * + * @retval true The delayed reception was scheduled and successfully cancelled + * or no receive window with given ID was found. + * @retval false No delayed reception was scheduled. + */ +bool nrf_802154_request_receive_at_scheduled_cancel(uint32_t id); + #endif // NRF_802154_DELAYED_TRX_ENABLED /** diff --git a/drivers/nrf_802154/driver/src/nrf_802154_request_direct.c b/drivers/nrf_802154/driver/src/nrf_802154_request_direct.c index 30b259c6..5805ec6a 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_request_direct.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_request_direct.c @@ -193,6 +193,11 @@ bool nrf_802154_request_receive_at_cancel(uint32_t id) REQUEST_FUNCTION_PARMS(nrf_802154_delayed_trx_receive_cancel, id); } +bool nrf_802154_request_receive_at_scheduled_cancel(uint32_t id) +{ + REQUEST_FUNCTION_PARMS(nrf_802154_delayed_trx_receive_scheduled_cancel, id); +} + #endif bool nrf_802154_request_csma_ca_start(uint8_t * p_data, diff --git a/drivers/nrf_802154/driver/src/nrf_802154_request_swi.c b/drivers/nrf_802154/driver/src/nrf_802154_request_swi.c index 8f74dd65..1e884e85 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_request_swi.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_request_swi.c @@ -93,6 +93,7 @@ typedef enum REQ_TYPE_TRANSMIT_AT_CANCEL, REQ_TYPE_RECEIVE_AT, REQ_TYPE_RECEIVE_AT_CANCEL, + REQ_TYPE_RECEIVE_AT_SCHEDULED_CANCEL, REQ_TYPE_CSMA_CA_START, } nrf_802154_req_type_t; @@ -655,6 +656,17 @@ static void swi_receive_at_cancel(uint32_t id, bool * p_result) req_exit(); } +static void swi_receive_at_scheduled_cancel(uint32_t id, bool * p_result) +{ + nrf_802154_req_data_t * p_slot = req_enter(); + + p_slot->type = REQ_TYPE_RECEIVE_AT_SCHEDULED_CANCEL; + p_slot->data.receive_at_cancel.id = id; + p_slot->data.receive_at_cancel.p_result = p_result; + + req_exit(); +} + #endif // NRF_802154_DELAYED_TRX_ENABLED static void swi_csma_ca_start(uint8_t * p_data, @@ -813,6 +825,13 @@ bool nrf_802154_request_receive_at_cancel(uint32_t id) REQUEST_FUNCTION(nrf_802154_delayed_trx_receive_cancel, swi_receive_at_cancel, id); } +bool nrf_802154_request_receive_at_scheduled_cancel(uint32_t id) +{ + REQUEST_FUNCTION(nrf_802154_delayed_trx_receive_scheduled_cancel, + swi_receive_at_scheduled_cancel, + id); +} + bool nrf_802154_request_csma_ca_start(uint8_t * p_data, const nrf_802154_transmit_csma_ca_metadata_t * p_metadata) { @@ -942,6 +961,12 @@ static void irq_handler_req_event(void) nrf_802154_delayed_trx_receive_cancel(p_slot->data.receive_at_cancel.id); break; + case REQ_TYPE_RECEIVE_AT_SCHEDULED_CANCEL: + *(p_slot->data.receive_at_cancel.p_result) = + nrf_802154_delayed_trx_receive_scheduled_cancel( + p_slot->data.receive_at_cancel.id); + break; + case REQ_TYPE_CSMA_CA_START: *(p_slot->data.csma_ca_start.p_result) = nrf_802154_csma_ca_start(p_slot->data.csma_ca_start.p_data, diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx.c b/drivers/nrf_802154/driver/src/nrf_802154_trx.c index d8a6a35b..806a949c 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx.c @@ -102,26 +102,33 @@ #define SHORTS_TX_ACK (NRF_RADIO_SHORT_TXREADY_START_MASK | \ NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) -#define SHORTS_MULTI_CCA_TX (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ - NRF_RADIO_SHORT_CCAIDLE_TXEN_MASK | \ - NRF_RADIO_SHORT_TXREADY_START_MASK | \ - NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) +/* The short CCAIDLE_TXEN is not used */ +#define SHORTS_CCAIDLE_TXEN 0U +#else +#define SHORTS_CCAIDLE_TXEN NRF_RADIO_SHORT_CCAIDLE_TXEN_MASK +#endif -#define SHORTS_CCA_TX (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ - NRF_RADIO_SHORT_CCABUSY_DISABLE_MASK | \ - NRF_RADIO_SHORT_CCAIDLE_TXEN_MASK | \ - NRF_RADIO_SHORT_TXREADY_START_MASK | \ - NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) +#define SHORTS_MULTI_CCA_TX (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ + SHORTS_CCAIDLE_TXEN | \ + NRF_RADIO_SHORT_TXREADY_START_MASK | \ + NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) -#define SHORTS_TX (NRF_RADIO_SHORT_TXREADY_START_MASK | \ - NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) +#define SHORTS_CCA_TX (NRF_RADIO_SHORT_RXREADY_CCASTART_MASK | \ + NRF_RADIO_SHORT_CCABUSY_DISABLE_MASK | \ + SHORTS_CCAIDLE_TXEN | \ + NRF_RADIO_SHORT_TXREADY_START_MASK | \ + NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) + +#define SHORTS_TX (NRF_RADIO_SHORT_TXREADY_START_MASK | \ + NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) #if !defined(NRF52_SERIES) -#define SHORTS_RX_ACK (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ - NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) +#define SHORTS_RX_ACK (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ + NRF_RADIO_SHORT_PHYEND_DISABLE_MASK) #else -#define SHORTS_RX_ACK (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ - NRF_RADIO_SHORT_END_DISABLE_MASK) +#define SHORTS_RX_ACK (NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK | \ + NRF_RADIO_SHORT_END_DISABLE_MASK) #endif @@ -136,15 +143,11 @@ #define CRC_LENGTH 2 ///< Length of CRC in 802.15.4 frames [bytes] #define CRC_POLYNOMIAL 0x011021 ///< Polynomial used for CRC calculation in 802.15.4 frames -#define TXRU_TIME 40 ///< Transmitter ramp up time [us] -#define EVENT_LAT 23 ///< END event latency [us] - #if !defined(CONFIG_SOC_SERIES_BSIM_NRFXX) #define MAX_RAMPDOWN_CYCLES (50 * (SystemCoreClock / 1000000UL)) ///< Maximum number of busy wait loop cycles that radio ramp-down is allowed to take #else #define MAX_RAMPDOWN_CYCLES 20 #endif -#define RSSI_SETTLE_TIME_US 15 ///< Time required for RSSI measurements to become valid after signal level change. #if NRF_802154_INTERNAL_RADIO_IRQ_HANDLING void nrf_802154_radio_irq_handler(void); ///< Prototype required by internal RADIO IRQ handler @@ -727,6 +730,12 @@ static void fem_for_tx_set(bool cca, mpsl_fem_pa_power_control_t pa_power_contro nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE0_STOP_MASK); nrf_802154_trx_ppi_for_fem_set(); } + else + { + nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE0_STOP_MASK); + nrf_timer_cc_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL0, 2); + } } static void fem_for_tx_reset(bool cca) @@ -1637,9 +1646,7 @@ void nrf_802154_trx_transmit_frame(const void * p_tra fem_for_tx_set(cca, p_tx_power->fem_pa_power_control); nrf_802154_trx_antenna_update(); - nrf_802154_trx_ppi_for_ramp_up_set(cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, - rampup_trigg_mode, - false); + nrf_802154_trx_ppi_for_txframe_ramp_up_set(cca, rampup_trigg_mode); if (rampup_trigg_mode == TRX_RAMP_UP_SW_TRIGGER) { @@ -1653,7 +1660,8 @@ bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_ { /* Assumptions on peripherals * TIMER is running, is counting from value saved in m_timer_value_on_radio_end_event, - * which trigered on END event, which happened EVENT_LAT us after frame on air receive was finished. + * which trigered on END event, which happened RX_PHYEND_EVENT_LATENCY_US us after frame + * on air receive was finished. * RADIO is DISABLED * PPIs are DISABLED */ @@ -1668,15 +1676,16 @@ bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_ m_trx_state = TRX_STATE_TXACK; // Set TIMER's CC to the moment when ramp-up should occur. - if (delay_us <= TXRU_TIME + EVENT_LAT) + if (delay_us <= TX_RAMP_UP_TIME + RX_PHYEND_EVENT_LATENCY_US) { timer_stop_and_clear(); nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_LOW); return result; } - uint32_t timer_cc_ramp_up_start = m_timer_value_on_radio_end_event + delay_us - TXRU_TIME - - EVENT_LAT; + uint32_t timer_cc_ramp_up_start = m_timer_value_on_radio_end_event + delay_us - + TX_RAMP_UP_TIME - + RX_PHYEND_EVENT_LATENCY_US; nrf_timer_cc_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_CC_CHANNEL1, @@ -1692,12 +1701,12 @@ bool nrf_802154_trx_transmit_ack(const void * p_transmit_buffer, uint32_t delay_ // Set FEM // Note: the TIMER is running, ramp up will start in timer_cc_ramp_up_start tick - // Assumption here is that FEM activation takes no more than TXRU_TIME. + // Assumption here is that FEM activation takes no more than TX_RAMP_UP_TIME. m_activate_tx_cc0_timeshifted = m_activate_tx_cc0; // Set the moment for FEM at which real transmission starts. m_activate_tx_cc0_timeshifted.event.timer.counter_period.end = timer_cc_ramp_up_start + - TXRU_TIME; + TX_RAMP_UP_TIME; if (mpsl_fem_pa_configuration_set(&m_activate_tx_cc0_timeshifted, NULL) == 0) { @@ -2537,7 +2546,7 @@ static void txframe_finish_disable_ppis(bool cca) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); - nrf_802154_trx_ppi_for_ramp_up_clear(cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, false); + nrf_802154_trx_ppi_for_txframe_ramp_up_clear(cca); nrf_802154_trx_ppi_for_extra_cca_attempts_clear(); // fine to call unconditionally nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx_dppi.c b/drivers/nrf_802154/driver/src/nrf_802154_trx_dppi.c index f5d98b5a..c71638e6 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx_dppi.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx_dppi.c @@ -59,6 +59,18 @@ #define PPI_TIMER_TX_ACK NRF_802154_DPPI_TIMER_COMPARE_TO_RADIO_TXEN #define PPI_RADIO_SYNC_EGU_SYNC NRF_802154_DPPI_RADIO_SYNC_TO_EGU_SYNC +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) +#define EGU_TIMER_START_EVENT NRFX_CONCAT_2(NRF_EGU_EVENT_TRIGGERED, \ + NRF_802154_EGU_TIMER_START_CHANNEL_NO) +#define EGU_TIMER_START_TASK NRFX_CONCAT_2(NRF_EGU_TASK_TRIGGER, \ + NRF_802154_EGU_TIMER_START_CHANNEL_NO) + +#define EGU_TIMER_START2_EVENT NRFX_CONCAT_2(NRF_EGU_EVENT_TRIGGERED, \ + NRF_802154_EGU_TIMER_START2_CHANNEL_NO) +#define EGU_TIMER_START2_TASK NRFX_CONCAT_2(NRF_EGU_TASK_TRIGGER, \ + NRF_802154_EGU_TIMER_START2_CHANNEL_NO) +#endif + void nrf_802154_trx_ppi_for_enable(void) { nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_DISABLED, PPI_DISABLED_EGU); @@ -69,6 +81,15 @@ void nrf_802154_trx_ppi_for_enable(void) nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_CCAIDLE, NRF_802154_DPPI_RADIO_CCAIDLE); nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY, NRF_802154_DPPI_RADIO_CCABUSY); +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) + nrf_egu_publish_set(NRF_802154_EGU_INSTANCE, + EGU_TIMER_START_EVENT, + NRF_802154_DPPI_TIMER_START); + nrf_timer_subscribe_set(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_TASK_START, + NRF_802154_DPPI_TIMER_START); +#endif + nrf_dppi_channels_enable(NRF_802154_DPPIC_INSTANCE, (1UL << NRF_802154_DPPI_RADIO_CCABUSY) | (1UL << PPI_DISABLED_EGU) | @@ -77,6 +98,9 @@ void nrf_802154_trx_ppi_for_enable(void) (1UL << NRF_802154_DPPI_RADIO_END) | (1UL << NRF_802154_DPPI_RADIO_PHYEND) | (1UL << NRF_802154_DPPI_RADIO_CCAIDLE) | +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) + (1UL << NRF_802154_DPPI_TIMER_START) | +#endif (1UL << NRF_802154_DPPI_RADIO_HW_TRIGGER)); } @@ -90,8 +114,16 @@ void nrf_802154_trx_ppi_for_disable(void) (1UL << NRF_802154_DPPI_RADIO_END) | (1UL << NRF_802154_DPPI_RADIO_PHYEND) | (1UL << NRF_802154_DPPI_RADIO_CCAIDLE) | +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) + (1UL << NRF_802154_DPPI_TIMER_START) | +#endif (1UL << NRF_802154_DPPI_RADIO_HW_TRIGGER)); +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) + nrf_timer_subscribe_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START); + nrf_egu_publish_clear(NRF_802154_EGU_INSTANCE, EGU_TIMER_START_EVENT); +#endif + #if NRF_802154_TEST_MODES_ENABLED nrf_radio_publish_clear(NRF_RADIO, NRF_RADIO_EVENT_CCABUSY); #endif // NRF_802154_TEST_MODES_ENABLED @@ -126,7 +158,13 @@ void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ra if (start_timer) { +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) + nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, + EGU_TIMER_START_TASK, + PPI_DISABLED_EGU); +#else nrf_timer_subscribe_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START, PPI_DISABLED_EGU); +#endif } nrf_egu_publish_set(NRF_802154_EGU_INSTANCE, EGU_EVENT, PPI_EGU_RAMP_UP); @@ -146,6 +184,70 @@ void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ra nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } +void nrf_802154_trx_ppi_for_txframe_ramp_up_set( + bool cca, + nrf_802154_trx_ramp_up_trigger_mode_t trigg_mode) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ramp_up_set( + cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, + trigg_mode, + false); + +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) + if (cca) + { + nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, + EGU_TIMER_START_TASK, + PPI_EGU_RAMP_UP); + + // Let the TIMER be started by RADIO.EVENTS_CCAIDLE + // Connections marked with (*) is already done by nrf_802154_trx_ppi_for_enable. + // + // EGU.EGU_TIMER_START_EVENT ---(*)-+--> NRF_802154_DPPI_TIMER_START <--(*)-- TIMER.TASKS_START + // EGU.EGU_TIMER_START2_EVENT ------/ + // + // RADIO.EVENTS_CCAIDLE --(*)-> NRF_802154_DPPI_RADIO_CCAIDLE <------ EGU.EGU_TIMER_START2_TASK + + nrf_egu_publish_set(NRF_802154_EGU_INSTANCE, + EGU_TIMER_START2_EVENT, + NRF_802154_DPPI_TIMER_START); + nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, + EGU_TIMER_START2_TASK, + NRF_802154_DPPI_RADIO_CCAIDLE); + + // Setup TIMER.CC[1] to a value when the RADIO.TASKS_TXEN should be triggered. + // The TIMER.CC[0] holds value at which the TIMER stopped after the ramp-up for CCA operation. + // The timer will continue counting from this value. + uint32_t timer_val_at_ccaidle = nrf_timer_cc_get(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_CC_CHANNEL0); + + nrf_timer_cc_set(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_CC_CHANNEL1, + timer_val_at_ccaidle + NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US); + nrf_timer_shorts_enable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE1_STOP_MASK); + + // Let the TIMER'.CC[1] trigger the RADIO.TASKS_TXEN + // + // TIMER.CC1 ----> NRF_802154_DPPI_RADIO_TXEN <----- RADIO.TASKS_TXEN + nrf_timer_publish_set(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_EVENT_COMPARE1, + NRF_802154_DPPI_RADIO_TXEN); + + nrf_radio_subscribe_set(NRF_RADIO, + NRF_RADIO_TASK_TXEN, + NRF_802154_DPPI_RADIO_TXEN); + + nrf_dppi_channels_enable(NRF_802154_DPPIC_INSTANCE, + (1UL << NRF_802154_DPPI_RADIO_TXEN)); + } +#endif + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + void nrf_802154_trx_ppi_for_extra_cca_attempts_set(void) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); @@ -171,6 +273,7 @@ void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool st nrf_egu_publish_clear(NRF_802154_EGU_INSTANCE, EGU_EVENT); nrf_radio_subscribe_clear(NRF_RADIO, ramp_up_task); nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_DISABLE); + nrf_dppi_subscribe_clear(NRF_802154_DPPIC_INSTANCE, DPPI_CHGRP_RAMP_UP_DIS_TASK); nrf_dppi_channels_remove_from_group(NRF_802154_DPPIC_INSTANCE, 1UL << PPI_EGU_RAMP_UP, @@ -178,7 +281,11 @@ void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool st if (start_timer) { +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) + nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, EGU_TIMER_START_TASK); +#else nrf_timer_subscribe_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START); +#endif } nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, EGU_TASK); @@ -186,6 +293,36 @@ void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool st nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } +void nrf_802154_trx_ppi_for_txframe_ramp_up_clear(bool cca) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) + if (cca) + { + nrf_dppi_channels_disable(NRF_802154_DPPIC_INSTANCE, + (1UL << NRF_802154_DPPI_RADIO_TXEN)); + nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN); + nrf_timer_publish_clear(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_EVENT_COMPARE1); + nrf_timer_shorts_disable(NRF_802154_TIMER_INSTANCE, + NRF_TIMER_SHORT_COMPARE1_STOP_MASK); + + nrf_egu_publish_clear(NRF_802154_EGU_INSTANCE, + EGU_TIMER_START2_EVENT); + nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, + EGU_TIMER_START2_TASK); + + nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, + EGU_TIMER_START_TASK); + } +#endif + + nrf_802154_trx_ppi_for_ramp_up_clear(cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, false); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + void nrf_802154_trx_ppi_for_extra_cca_attempts_clear(void) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); @@ -260,7 +397,13 @@ void nrf_802154_trx_ppi_for_fem_set(void) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) + nrf_egu_subscribe_set(NRF_802154_EGU_INSTANCE, + EGU_TIMER_START_TASK, + PPI_DISABLED_EGU); +#else nrf_timer_subscribe_set(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START, PPI_DISABLED_EGU); +#endif nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } @@ -269,7 +412,11 @@ void nrf_802154_trx_ppi_for_fem_clear(void) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) + nrf_egu_subscribe_clear(NRF_802154_EGU_INSTANCE, EGU_TIMER_START_TASK); +#else nrf_timer_subscribe_clear(NRF_802154_TIMER_INSTANCE, NRF_TIMER_TASK_START); +#endif nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi.c b/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi.c index ef5e2d13..722c0e02 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi.c +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi.c @@ -136,6 +136,24 @@ void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ra nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } +void nrf_802154_trx_ppi_for_txframe_ramp_up_set( + bool cca, + nrf_802154_trx_ramp_up_trigger_mode_t trigg_mode) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ramp_up_set( + cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, + trigg_mode, + false); + +#if (NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US != 0) +#error NRF_802154_CCAIDLE_TO_TXEN_EXTRA_TIME_US is unsupported for the selected SoC +#endif + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + void nrf_802154_trx_ppi_for_extra_cca_attempts_set(void) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); @@ -188,6 +206,15 @@ void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool st nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); } +void nrf_802154_trx_ppi_for_txframe_ramp_up_clear(bool cca) +{ + nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); + + nrf_802154_trx_ppi_for_ramp_up_clear(cca ? NRF_RADIO_TASK_RXEN : NRF_RADIO_TASK_TXEN, false); + + nrf_802154_log_function_exit(NRF_802154_LOG_VERBOSITY_HIGH); +} + void nrf_802154_trx_ppi_for_extra_cca_attempts_clear(void) { nrf_802154_log_function_enter(NRF_802154_LOG_VERBOSITY_HIGH); diff --git a/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi_api.h b/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi_api.h index 35e86941..bdf41cd9 100644 --- a/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi_api.h +++ b/drivers/nrf_802154/driver/src/nrf_802154_trx_ppi_api.h @@ -110,6 +110,16 @@ void nrf_802154_trx_ppi_for_ramp_up_set(nrf_radio_task_t ra nrf_802154_trx_ramp_up_trigger_mode_t trigg_mode, bool start_timer); +/** + * @brief Set (D)PPIs to connect trigger event with tasks needed to ramp up for a transmission of a frame. + * + * @param[in] cca Transmission with preceding CCA operation. + * @param[in] trigg_mode Trigger mode the connections must conform to. + */ +void nrf_802154_trx_ppi_for_txframe_ramp_up_set( + bool cca, + nrf_802154_trx_ramp_up_trigger_mode_t trigg_mode); + /** * @brief Set (D)PPIs to perform CCA procedures back-to-back. */ @@ -134,6 +144,15 @@ void nrf_802154_trx_ppi_for_ramp_up_reconfigure(void); */ void nrf_802154_trx_ppi_for_ramp_up_clear(nrf_radio_task_t ramp_up_task, bool start_timer); +/** + * @brief Clear (D)PPIs that are configured for ramp up procedure for a transmission of a frame. + * + * @note Complementary to @ref nrf_802154_trx_ppi_for_txframe_ramp_up_set. + * + * @param cca Transmission with preceding CCA operation. + */ +void nrf_802154_trx_ppi_for_txframe_ramp_up_clear(bool cca); + /** * @brief Clear (D)PPIs to perform CCA procedures back-to-back. */ diff --git a/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h b/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h index 43b0dc83..ede823b9 100644 --- a/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h +++ b/drivers/nrf_802154/serialization/src/include/nrf_802154_spinel_datatypes.h @@ -477,6 +477,12 @@ typedef enum SPINEL_PROP_VENDOR_NORDIC_NRF_802154_ACK_DATA_REMOVE_ALL = SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 68, + /** + * Vendor property for nrf_802154_receive_at_scheduled_cancel serialization. + */ + SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL = + SPINEL_PROP_VENDOR_NORDIC_NRF_802154__BEGIN + 69, + } spinel_prop_vendor_key_t; /** @@ -841,132 +847,142 @@ typedef enum /** * @brief Spinel data type description for nrf_802154_receive_at result. */ -#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_RET SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_RET SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_receive_at_cancel. */ -#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_CANCEL SPINEL_DATATYPE_UINT32_S +#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_CANCEL SPINEL_DATATYPE_UINT32_S /** * @brief Spinel data type description for nrf_802154_receive_at_cancel result. */ -#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_CANCEL_RET SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_CANCEL_RET SPINEL_DATATYPE_BOOL_S + +/** + * @brief Spinel data type description for nrf_802154_receive_at_scheduled_cancel. + */ +#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL SPINEL_DATATYPE_UINT32_S + +/** + * @brief Spinel data type description for nrf_802154_receive_at_scheduled_cancel result. + */ +#define SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL_RET SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_pan_id_set. */ -#define SPINEL_DATATYPE_NRF_802154_PAN_ID_SET SPINEL_DATATYPE_DATA_S +#define SPINEL_DATATYPE_NRF_802154_PAN_ID_SET SPINEL_DATATYPE_DATA_S /** * @brief Spinel data type description for nrf_802154_short_address_set. */ -#define SPINEL_DATATYPE_NRF_802154_SHORT_ADDRESS_SET SPINEL_DATATYPE_DATA_S +#define SPINEL_DATATYPE_NRF_802154_SHORT_ADDRESS_SET SPINEL_DATATYPE_DATA_S /** * @brief Spinel data type description for nrf_802154_extended_address_set. */ -#define SPINEL_DATATYPE_NRF_802154_EXTENDED_ADDRESS_SET SPINEL_DATATYPE_DATA_S +#define SPINEL_DATATYPE_NRF_802154_EXTENDED_ADDRESS_SET SPINEL_DATATYPE_DATA_S /** * @brief Spinel data type description for nrf_802154_pan_coord_set. */ -#define SPINEL_DATATYPE_NRF_802154_PAN_COORD_SET SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_PAN_COORD_SET SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_pan_coord_get result. */ -#define SPINEL_DATATYPE_NRF_802154_PAN_COORD_GET_RET SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_PAN_COORD_GET_RET SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_pan_coord_get. */ -#define SPINEL_DATATYPE_NRF_802154_PAN_COORD_GET SPINEL_DATATYPE_NULL_S +#define SPINEL_DATATYPE_NRF_802154_PAN_COORD_GET SPINEL_DATATYPE_NULL_S /** * @brief Spinel data type description for nrf_802154_promiscuous_set. */ -#define SPINEL_DATATYPE_NRF_802154_PROMISCUOUS_SET SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_PROMISCUOUS_SET SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_rx_on_when_idle_set. */ -#define SPINEL_DATATYPE_NRF_802154_RX_ON_WHEN_IDLE_SET SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_RX_ON_WHEN_IDLE_SET SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_cca. */ -#define SPINEL_DATATYPE_NRF_802154_CCA SPINEL_DATATYPE_NULL_S +#define SPINEL_DATATYPE_NRF_802154_CCA SPINEL_DATATYPE_NULL_S /** * @brief Spinel data type description for nrf_802154_cca result. */ -#define SPINEL_DATATYPE_NRF_802154_CCA_RET SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_CCA_RET SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_cca_done. */ -#define SPINEL_DATATYPE_NRF_802154_CCA_DONE SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_CCA_DONE SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_cca_failed. */ -#define SPINEL_DATATYPE_NRF_802154_CCA_FAILED SPINEL_DATATYPE_UINT8_S +#define SPINEL_DATATYPE_NRF_802154_CCA_FAILED SPINEL_DATATYPE_UINT8_S /** * @brief Spinel data type description for nrf_802154_energy_detection. */ -#define SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTION SPINEL_DATATYPE_UINT32_S +#define SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTION SPINEL_DATATYPE_UINT32_S /** * @brief Spinel data type description for nrf_802154_energy_detection result. */ -#define SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTION_RET SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTION_RET SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_energy_detected. */ -#define SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTED SPINEL_DATATYPE_INT8_S +#define SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTED SPINEL_DATATYPE_INT8_S /** * @brief Spinel data type description for nrf_802154_energy_detection_failed. */ -#define SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTION_FAILED SPINEL_DATATYPE_UINT8_S +#define SPINEL_DATATYPE_NRF_802154_ENERGY_DETECTION_FAILED SPINEL_DATATYPE_UINT8_S /** * @brief Spinel data type description for nrf_802154_continuous_carrier. */ -#define SPINEL_DATATYPE_NRF_802154_CONTINUOUS_CARRIER SPINEL_DATATYPE_NULL_S +#define SPINEL_DATATYPE_NRF_802154_CONTINUOUS_CARRIER SPINEL_DATATYPE_NULL_S /** * @brief Spinel data type description for nrf_802154_nrf_802154_continuous_carrier result. */ -#define SPINEL_DATATYPE_NRF_802154_CONTINUOUS_CARRIER_RET SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_CONTINUOUS_CARRIER_RET SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_modulated_carrier. */ -#define SPINEL_DATATYPE_NRF_802154_MODULATED_CARRIER SPINEL_DATATYPE_DATA_S +#define SPINEL_DATATYPE_NRF_802154_MODULATED_CARRIER SPINEL_DATATYPE_DATA_S /** * @brief Spinel data type description for nrf_802154_nrf_802154_modulated_carrier result. */ -#define SPINEL_DATATYPE_NRF_802154_MODULATED_CARRIER_RET SPINEL_DATATYPE_BOOL_S +#define SPINEL_DATATYPE_NRF_802154_MODULATED_CARRIER_RET SPINEL_DATATYPE_BOOL_S /** * @brief Spinel data type description for nrf_802154_tx_power_get. */ -#define SPINEL_DATATYPE_NRF_802154_TX_POWER_GET SPINEL_DATATYPE_NULL_S +#define SPINEL_DATATYPE_NRF_802154_TX_POWER_GET SPINEL_DATATYPE_NULL_S /** * @brief Spinel data type description for nrf_802154_tx_power_get result. */ -#define SPINEL_DATATYPE_NRF_802154_TX_POWER_GET_RET SPINEL_DATATYPE_INT8_S +#define SPINEL_DATATYPE_NRF_802154_TX_POWER_GET_RET SPINEL_DATATYPE_INT8_S /** * @brief Spinel data type description for nrf_802154_tx_power_set. */ -#define SPINEL_DATATYPE_NRF_802154_TX_POWER_SET SPINEL_DATATYPE_INT8_S +#define SPINEL_DATATYPE_NRF_802154_TX_POWER_SET SPINEL_DATATYPE_INT8_S /** * @brief Spinel data type description for nrf_802154_received_timestamp_raw diff --git a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c index 42437dd5..4684bab9 100644 --- a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c +++ b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_app.c @@ -572,6 +572,36 @@ bool nrf_802154_receive_at_cancel(uint32_t id) return cancel_result; } +bool nrf_802154_receive_at_scheduled_cancel(uint32_t id) +{ + nrf_802154_ser_err_t res; + bool cancel_result = false; + + SERIALIZATION_ERROR_INIT(error); + + NRF_802154_SPINEL_LOG_BANNER_CALLING(); + + nrf_802154_spinel_response_notifier_lock_before_request( + SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL); + + res = nrf_802154_spinel_send_cmd_prop_value_set( + SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL, + SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL, + id); + + SERIALIZATION_ERROR_CHECK(res, error, bail); + + res = net_generic_bool_response_await(CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT, + &cancel_result); + + SERIALIZATION_ERROR_CHECK(res, error, bail); + +bail: + SERIALIZATION_ERROR_RAISE_IF_FAILED(error); + + return cancel_result; +} + void nrf_802154_pan_id_set(const uint8_t * p_pan_id) { nrf_802154_ser_err_t res; @@ -1076,7 +1106,8 @@ bool nrf_802154_cca(void) NRF_802154_SPINEL_LOG_BANNER_CALLING(); - nrf_802154_spinel_response_notifier_lock_before_request(SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA); + nrf_802154_spinel_response_notifier_lock_before_request( + SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA); res = nrf_802154_spinel_send_cmd_prop_value_set( SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA, @@ -2049,8 +2080,9 @@ void nrf_802154_csl_writer_anchor_time_set(uint64_t anchor_time) return; } -static nrf_802154_ser_err_t stat_timestamps_get_ret_await(uint32_t timeout, - nrf_802154_stat_timestamps_t * p_stat_timestamps) +static nrf_802154_ser_err_t stat_timestamps_get_ret_await( + uint32_t timeout, + nrf_802154_stat_timestamps_t * p_stat_timestamps) { nrf_802154_ser_err_t res; nrf_802154_spinel_notify_buff_t * p_notify_data = NULL; diff --git a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_app.c b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_app.c index 658f8bae..76b60238 100644 --- a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_app.c +++ b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_app.c @@ -586,6 +586,8 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_is( // fall through case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_CANCEL: // fall through + case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL: + // fall through case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CCA: // fall through #if NRF_802154_CARRIER_FUNCTIONS_ENABLED diff --git a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c index 5fd552cc..0d2c807c 100644 --- a/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c +++ b/drivers/nrf_802154/serialization/src/nrf_802154_spinel_dec_net.c @@ -191,6 +191,38 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_receive_at_cancel( result); } +/** + * @brief Decode and dispatch SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL. + * + * @param[in] p_property_data Pointer to a buffer that contains data to be decoded. + * @param[in] property_data_len Size of the @ref p_property_data buffer. + * + */ +static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_receive_at_scheduled_cancel( + const void * p_property_data, + size_t property_data_len) +{ + uint32_t id; + spinel_ssize_t siz; + + siz = spinel_datatype_unpack(p_property_data, + property_data_len, + SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL, + &id); + + if (siz < 0) + { + return NRF_802154_SERIALIZATION_ERROR_DECODING_FAILURE; + } + + bool result = nrf_802154_receive_at_scheduled_cancel(id); + + return nrf_802154_spinel_send_cmd_prop_value_is( + SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL, + SPINEL_DATATYPE_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL_RET, + result); +} + #endif // NRF_802154_DELAYED_TRX_ENABLED static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_channel_get(const void * p_property_data, @@ -1551,8 +1583,9 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_buffer_free_raw( * @param[in] property_data_len Size of the @ref p_property_data buffer. * */ -static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_tx_power_set(const void * p_property_data, - size_t property_data_len) +static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_tx_power_set( + const void * p_property_data, + size_t property_data_len) { spinel_ssize_t siz; int8_t power; @@ -1578,8 +1611,9 @@ static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_tx_power_set(const voi * @param[in] property_data_len Size of the @ref p_property_data buffer. * */ -static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_tx_power_get(const void * p_property_data, - size_t property_data_len) +static nrf_802154_ser_err_t spinel_decode_prop_nrf_802154_tx_power_get( + const void * p_property_data, + size_t property_data_len) { (void)p_property_data; (void)property_data_len; @@ -1939,6 +1973,10 @@ nrf_802154_ser_err_t nrf_802154_spinel_decode_cmd_prop_value_set(const void * p_ return spinel_decode_prop_nrf_802154_receive_at_cancel(p_property_data, property_data_len); + case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_RECEIVE_AT_SCHEDULED_CANCEL: + return spinel_decode_prop_nrf_802154_receive_at_scheduled_cancel(p_property_data, + property_data_len); + #endif // NRF_802154_DELAYED_TRX_ENABLED case SPINEL_PROP_VENDOR_NORDIC_NRF_802154_CHANNEL_GET: return spinel_decode_prop_nrf_802154_channel_get(p_property_data, property_data_len); diff --git a/drivers/nrf_802154/sl/include/nrf_802154_sl_atomic_list.h b/drivers/nrf_802154/sl/include/nrf_802154_sl_atomic_list.h index b292956e..c885c953 100644 --- a/drivers/nrf_802154/sl/include/nrf_802154_sl_atomic_list.h +++ b/drivers/nrf_802154/sl/include/nrf_802154_sl_atomic_list.h @@ -104,10 +104,11 @@ void nrf_802154_sl_atomic_list_init(nrf_802154_sl_atomic_list_t * p_list); * returns -1. When such match is found the @p p_item is inserted * before @c entry. */ -void nrf_802154_sl_atomic_list_insert_ordered(nrf_802154_sl_atomic_list_t * p_list, - void * p_item, - size_t offsetof_membership_capability, - nrf_802154_sl_compare_func_t compare_func); +void nrf_802154_sl_atomic_list_insert_ordered( + nrf_802154_sl_atomic_list_t * p_list, + void * p_item, + size_t offsetof_membership_capability, + nrf_802154_sl_compare_func_t compare_func); /**@brief Atomically removes an item from a list. * diff --git a/drivers/nrf_802154/sl/sl_opensource/include/protocol/mpsl_fem_protocol_api.h b/drivers/nrf_802154/sl/sl_opensource/include/protocol/mpsl_fem_protocol_api.h index 33954f0a..fa20a325 100644 --- a/drivers/nrf_802154/sl/sl_opensource/include/protocol/mpsl_fem_protocol_api.h +++ b/drivers/nrf_802154/sl/sl_opensource/include/protocol/mpsl_fem_protocol_api.h @@ -408,28 +408,6 @@ int8_t mpsl_fem_tx_power_split(const mpsl_tx_power_t power, */ int32_t mpsl_fem_pa_power_control_set(mpsl_fem_pa_power_control_t pa_power_control); -/** @brief Prepares the Front End Module to switch to the Power Down state. - * - * @deprecated This function is deprecated. Use @ref mpsl_fem_disable instead. - * - * This function makes sure the Front End Module shall be switched off in the - * appropriate time, using the hardware timer and its compare channel. - * The timer is owned by the protocol and must be started by the protocol. - * The timer stops after matching the provided compare channel (the call sets the short). - * - * @param[in] p_instance Timer instance that is used to schedule the transition to the Power Down state. - * @param[in] compare_channel Compare channel to hold a value for the timer. - * @param[in] ppi_id ID of the PPI channel used to switch to the Power Down state. - * @param[in] event_addr Address of the event which shall trigger the Timer start. - * - * @retval true Whether the scheduling of the transition was successful. - * @retval false Whether the scheduling of the transition was not successful. - */ -bool mpsl_fem_prepare_powerdown(NRF_TIMER_Type * p_instance, - uint32_t compare_channel, - uint32_t ppi_id, - uint32_t event_addr); - #endif // MPSL_FEM_PROTOCOL_API_H__ /**@} */ diff --git a/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_fem.c b/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_fem.c index 55c47eff..87467d2d 100644 --- a/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_fem.c +++ b/drivers/nrf_802154/sl/sl_opensource/src/nrf_802154_sl_fem.c @@ -216,18 +216,6 @@ int32_t mpsl_fem_pa_power_control_set(mpsl_fem_pa_power_control_t pa_power_contr return 0; } -bool mpsl_fem_prepare_powerdown(NRF_TIMER_Type * p_instance, - uint32_t compare_channel, - uint32_t ppi_id, - uint32_t event_addr) -{ - (void)p_instance; - (void)compare_channel; - (void)ppi_id; - - return false; -} - bool mpsl_fem_device_config_254_apply_get(void) { return false;