[nrf52840] update radio driver to version 1.1.0 (#2646)

This commit is contained in:
Hubert Miś
2018-04-04 09:26:07 -07:00
committed by Jonathan Hui
parent 477fd5cebb
commit 8b66cb0fe8
16 changed files with 436 additions and 245 deletions
+3
View File
@@ -742,6 +742,9 @@ void nrf_802154_transmit_failed(const uint8_t *aFrame, nrf_802154_tx_error_t err
case NRF_802154_TX_ERROR_NO_MEM:
setPendingEvent(kPendingEventInvalidOrNoAck);
break;
default:
assert(false);
}
}
@@ -370,7 +370,7 @@ static bool dst_extended_addr_check(const uint8_t *p_psdu)
nrf_802154_rx_error_t nrf_802154_filter_frame_part(const uint8_t * p_psdu, uint8_t * p_num_bytes)
{
nrf_802154_rx_error_t result;
nrf_802154_rx_error_t result = NRF_802154_RX_ERROR_INVALID_FRAME;
switch (*p_num_bytes)
{
@@ -150,6 +150,11 @@ int8_t nrf_802154_dbm_from_energy_level_calculate(uint8_t energy_level)
return ED_MIN_DBM + (energy_level / ED_RESULT_FACTOR);
}
uint8_t nrf_802154_ccaedthres_from_dbm_calculate(int8_t dbm)
{
return dbm - ED_MIN_DBM;
}
uint32_t nrf_802154_first_symbol_timestamp_get(uint32_t end_timestamp, uint8_t psdu_length)
{
uint32_t frame_symbols = PHY_SHR_DURATION;
@@ -334,15 +339,33 @@ void nrf_802154_buffer_free_raw(uint8_t * p_data)
rx_buffer_t * p_buffer = (rx_buffer_t *)p_data;
assert(p_buffer->free == false);
(void)p_buffer;
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_BUFFER_FREE);
result = nrf_802154_request_buffer_free(p_data);
assert(result);
(void)result;
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_BUFFER_FREE);
}
bool nrf_802154_buffer_free_immediately_raw(uint8_t * p_data)
{
bool result;
rx_buffer_t * p_buffer = (rx_buffer_t *)p_data;
assert(p_buffer->free == false);
(void)p_buffer;
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_BUFFER_FREE);
result = nrf_802154_request_buffer_free(p_data);
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_BUFFER_FREE);
return result;
}
#else // NRF_802154_USE_RAW_API
void nrf_802154_buffer_free(uint8_t * p_data)
@@ -351,15 +374,33 @@ void nrf_802154_buffer_free(uint8_t * p_data)
rx_buffer_t * p_buffer = (rx_buffer_t *)(p_data - RAW_PAYLOAD_OFFSET);
assert(p_buffer->free == false);
(void)p_buffer;
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_BUFFER_FREE);
result = nrf_802154_request_buffer_free(p_data - RAW_PAYLOAD_OFFSET);
assert(result);
(void)result;
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_BUFFER_FREE);
}
bool nrf_802154_buffer_free_immediately(uint8_t * p_data)
{
bool result;
rx_buffer_t * p_buffer = (rx_buffer_t *)(p_data - RAW_PAYLOAD_OFFSET);
assert(p_buffer->free == false);
(void)p_buffer;
nrf_802154_log(EVENT_TRACE_ENTER, FUNCTION_BUFFER_FREE);
result = nrf_802154_request_buffer_free(p_data - RAW_PAYLOAD_OFFSET);
nrf_802154_log(EVENT_TRACE_EXIT, FUNCTION_BUFFER_FREE);
return result;
}
#endif // NRF_802154_USE_RAW_API
int8_t nrf_802154_rssi_last_get(void)
+174 -118
View File
@@ -74,8 +74,8 @@ void nrf_802154_deinit(void);
* @note If NRF_802154_INTERNAL_RADIO_IRQ_HANDLING is enabled, the driver internally handles the
* RADIO IRQ, and this function shall not be called.
*
* This function should be used in an operating system environment where the OS handles IRQ
* and indirectly passes it to the driver, or with a RAAL implementation that indirectly passes radio
* This function should be used in an operating system environment where the OS handles IRQ and
* indirectly passes it to the driver, or with a RAAL implementation that indirectly passes radio
* IRQ to the driver (i.e. SoftDevice).
*/
void nrf_802154_radio_irq_handler(void);
@@ -211,6 +211,16 @@ void nrf_802154_short_address_set(const uint8_t *p_short_address);
*/
int8_t nrf_802154_dbm_from_energy_level_calculate(uint8_t energy_level);
/**
* @brief Calculate the CCA energy detection threshold value from a given dBm level.
*
* @param[in] dbm Energy level in dBm used to calculate the CCAEDTHRES value.
*
* @return Energy level value corresponding to the given dBm level that should be written to
* the CCACTRL register.
*/
uint8_t nrf_802154_ccaedthres_from_dbm_calculate(int8_t dbm);
/**
* @brief Calculate the timestamp of the first symbol of the preamble in a received frame.
*
@@ -236,11 +246,12 @@ nrf_802154_state_t nrf_802154_state_get(void);
/**
* @brief Change radio state to sleep.
*
* Sleep state is the lowest power state. In this state, the radio cannot transmit or receive frames.
* It is the only state in which the driver releases the high-frequency clock and does not request
* timeslots from a radio arbiter.
* Sleep state is the lowest power state. In this state, the radio cannot transmit or receive
* frames. It is the only state in which the driver releases the high-frequency clock and does not
* request timeslots from a radio arbiter.
*
* @note If another module requests it, the high-frequency clock may be enabled even in radio sleep state.
* @note If another module requests it, the high-frequency clock may be enabled even in radio sleep
* state.
*
* @retval true If the radio changes its state to low power mode.
* @retval false If the driver could not schedule changing state.
@@ -250,8 +261,9 @@ bool nrf_802154_sleep(void);
/**
* @brief Change radio state to receive.
*
* In receive state, the radio receives frames and may automatically send ACK frames when appropriate.
* The received frame is reported to higher layer by a call to @ref nrf_802154_received.
* In receive state, the radio receives frames and may automatically send ACK frames when
* appropriate. The received frame is reported to higher layer by a call to
* @ref nrf_802154_received.
*
* @retval true If the radio enters receive state.
* @retval false If the driver could not enter receive state.
@@ -263,18 +275,18 @@ bool nrf_802154_receive(void);
* @brief Change radio state to transmit.
*
* @note If the CPU is halted or interrupted while this function is executed,
* @ref nrf_802154_transmitted or @ref nrf_802154_transmit_failed may be
* called before this function returns a result.
* @ref nrf_802154_transmitted or @ref nrf_802154_transmit_failed may be called before this
* function returns a result.
* @note This function is implemented in zero-copy fashion. It passes the given buffer pointer to
* the RADIO peripheral.
*
* In transmit state, the radio transmits a given frame. If requested, it waits for an ACK frame.
* Depending on @ref NRF_802154_ACK_TIMEOUT_ENABLED, the radio driver automatically
* stops waiting for an ACK frame or waits indefinitely for an ACK frame. If it is configured to wait,
* the MAC layer is responsible for calling @ref nrf_802154_receive or
* stops waiting for an ACK frame or waits indefinitely for an ACK frame. If it is configured to
* wait, the MAC layer is responsible for calling @ref nrf_802154_receive or
* @ref nrf_802154_sleep after the ACK time-out.
* The transmission result is reported to the higher layer by calls to @ref nrf_802154_transmitted or
* @ref nrf_802154_transmit_failed.
* The transmission result is reported to the higher layer by calls to @ref nrf_802154_transmitted
* or @ref nrf_802154_transmit_failed.
*
* @verbatim
* p_data
@@ -286,11 +298,11 @@ bool nrf_802154_receive(void);
* | <---------------------------- PHR -----------------------------------> |
* @endverbatim
*
* @param[in] p_data Pointer to array containing data to transmit. First byte should contain
* frame length (including PHR and FCS). Following bytes should contain data.
* CRC is computed automatically by radio hardware. Therefore, the FCS
* field can contain any bytes.
* @param[in] cca If the driver should perform a CCA procedure before transmission.
* @param[in] p_data Pointer to array containing data to transmit. First byte should contain frame
* length (including PHR and FCS). Following bytes should contain data. CRC is
* computed automatically by radio hardware. Therefore, the FCS field can
* contain any bytes.
* @param[in] cca If the driver should perform a CCA procedure before transmission.
*
* @retval true If the transmission procedure was scheduled.
* @retval false If the driver could not schedule the transmission procedure.
@@ -303,19 +315,19 @@ bool nrf_802154_transmit_raw(const uint8_t * p_data, bool cca);
* @brief Change radio state to transmit.
*
* @note If the CPU is halted or interrupted while this function is executed,
* @ref nrf_802154_transmitted or @ref nrf_802154_transmit_failed must be
* called before this function returns a result.
* @note This function copies the given buffer. It maintains an internal buffer, which
* is used to make a frame copy. To prevent unnecessary memory consumption and
* to perform zero-copy transmission, use @ref nrf_802154_transmit_raw instead.
* @ref nrf_802154_transmitted or @ref nrf_802154_transmit_failed must be called before this
* function returns a result.
* @note This function copies the given buffer. It maintains an internal buffer, which is used to
* make a frame copy. To prevent unnecessary memory consumption and to perform zero-copy
* transmission, use @ref nrf_802154_transmit_raw instead.
*
* In transmit state, the radio transmits a given frame. If requested, it waits for an ACK frame.
* Depending on @ref NRF_802154_ACK_TIMEOUT_ENABLED, the radio driver automatically
* stops waiting for an ACK frame or waits indefinitely for an ACK frame. If it is configured to wait,
* the MAC layer is responsible for calling @ref nrf_802154_receive or
* stops waiting for an ACK frame or waits indefinitely for an ACK frame. If it is configured to
* wait, the MAC layer is responsible for calling @ref nrf_802154_receive or
* @ref nrf_802154_sleep after the ACK time-out.
* The transmission result is reported to the higher layer by calls to @ref nrf_802154_transmitted or
* @ref nrf_802154_transmit_failed.
* The transmission result is reported to the higher layer by calls to @ref nrf_802154_transmitted
* or @ref nrf_802154_transmit_failed.
*
* @verbatim
* p_data
@@ -327,11 +339,11 @@ bool nrf_802154_transmit_raw(const uint8_t * p_data, bool cca);
* | <------------------ length -----------------------------> |
* @endverbatim
*
* @param[in] p_data Pointer to array containing payload of data to transmit. The array
* should exclude PHR or FCS fields of the 802.15.4 frame.
* @param[in] length Length of the given frame. This value shall exclude PHR and FCS fields from
* the given frame (exact size of buffer pointed to by @p p_data).
* @param[in] cca If the driver should perform a CCA procedure before transmission.
* @param[in] p_data Pointer to array containing payload of data to transmit. The array should
* exclude PHR or FCS fields of the 802.15.4 frame.
* @param[in] length Length of the given frame. This value shall exclude PHR and FCS fields from
* the given frame (exact size of buffer pointed to by @p p_data).
* @param[in] cca If the driver should perform a CCA procedure before transmission.
*
* @retval true If the transmission procedure was scheduled.
* @retval false If the driver could not schedule the transmission procedure.
@@ -343,15 +355,15 @@ bool nrf_802154_transmit(const uint8_t * p_data, uint8_t length, bool cca);
/**
* @brief Change radio state to energy detection.
*
* In energy detection state, the radio detects the maximum energy for a given time. The result of the detection
* is reported to the higher layer by @ref nrf_802154_energy_detected.
* In energy detection state, the radio detects the maximum energy for a given time. The result of
* the detection is reported to the higher layer by @ref nrf_802154_energy_detected.
*
* @note @ref nrf_802154_energy_detected may be called before this function returns a result.
* @note Performing the energy detection procedure make take longer time than requested in @p time_us.
* The procedure is performed only during timeslots granted by a radio arbiter. It may be
* interrupted by other protocols using the radio hardware. If the procedure is interrupted, it is
* automatically continued and the sum of time periods during which the procedure is carried
* out is not less than the requested @p time_us.
* @note Performing the energy detection procedure make take longer time than requested in
* @p time_us. The procedure is performed only during timeslots granted by a radio arbiter.
* It may be interrupted by other protocols using the radio hardware. If the procedure is
* interrupted, it is automatically continued and the sum of time periods during which the
* procedure is carried out is not less than the requested @p time_us.
*
* @param[in] time_us Duration of energy detection procedure. The given value is rounded up to
* multiplication of 8s (128 us).
@@ -366,8 +378,8 @@ bool nrf_802154_energy_detection(uint32_t time_us);
*
* @note @ref nrf_802154_cca_done may be called before this function returns a result.
*
* In CCA state, the radio verifies if the channel is clear. The result of the verification is reported to the higher
* layer by @ref nrf_802154_cca_done.
* In CCA state, the radio verifies if the channel is clear. The result of the verification is
* reported to the higher layer by @ref nrf_802154_cca_done.
*
* @retval true If the CCA procedure was scheduled.
* @retval false If the driver could not schedule the CCA procedure.
@@ -377,9 +389,9 @@ bool nrf_802154_cca(void);
/**
* @brief Change radio state to continuous carrier.
*
* @note When the radio is emitting continuous carrier signals, it blocks all transmissions on the selected channel.
* This function should be called only during radio tests. It should not be used during
* normal device operation.
* @note When the radio is emitting continuous carrier signals, it blocks all transmissions on the
* selected channel. This function should be called only during radio tests. It should not be
* used during normal device operation.
* @note This function works correctly only with a single-PHY arbiter. It should not be used with
* any other arbiter.
*
@@ -407,8 +419,8 @@ extern void nrf_802154_tx_ack_started(void);
/**
* @brief Notify that a frame was received.
*
* @note The buffer pointed to by @p p_data is not modified by the radio driver (and cannot
* be used to receive a frame) until @ref nrf_802154_buffer_free_raw is called.
* @note The buffer pointed to by @p p_data is not modified by the radio driver (and cannot be used
* to receive a frame) until @ref nrf_802154_buffer_free_raw is called.
* @note The buffer pointed to by @p p_data may be modified by the function handler (and other
* modules) until @ref nrf_802154_buffer_free_raw is called.
*
@@ -423,9 +435,9 @@ extern void nrf_802154_tx_ack_started(void);
* @endverbatim
*
* @param[in] p_data Pointer to the buffer containing received data (PHR + PSDU). First byte in
* the buffer is length of the frame (PHR). The following bytes contain the frame
* itself (PSDU). The length byte (PHR) includes FCS. FCS is already verified by
* the hardware and may be modified by the hardware.
* the buffer is length of the frame (PHR). The following bytes contain the
* frame itself (PSDU). The length byte (PHR) includes FCS. FCS is already
* verified by the hardware and may be modified by the hardware.
* @param[in] power RSSI of received frame.
* @param[in] lqi LQI of received frame.
*/
@@ -451,7 +463,8 @@ extern void nrf_802154_received_raw(uint8_t * p_data, int8_t power, uint8_t lqi)
* | <------------------ length -----------------------------> |
* @endverbatim
*
* @param[in] p_data Pointer to the buffer containing the payload of the received frame (PSDU without FCS).
* @param[in] p_data Pointer to the buffer containing the payload of the received frame (PSDU
* without FCS).
* @param[in] length Length of received payload.
* @param[in] power RSSI of received frame.
* @param[in] lqi LQI of received frame.
@@ -469,15 +482,15 @@ extern void nrf_802154_received(uint8_t * p_data, uint8_t length, int8_t power,
* list.
*
* @note @p timestamp may be inaccurate due to software latency (IRQ handling).
* @note @p timestamp granularity depends on the granularity of the timer driver in the platform/timer
* directory.
* @note Including the timestamp for received frames uses resources like CPU time and memory. If the timestamp
* is not required, use @ref nrf_802154_received_raw instead.
* @note @p timestamp granularity depends on the granularity of the timer driver in the
* platform/timer directory.
* @note Including the timestamp for received frames uses resources like CPU time and memory. If the
* timestamp is not required, use @ref nrf_802154_received_raw instead.
*
* @param[in] p_data Pointer to the buffer containing received data (PHR + PSDU). First byte in
* the buffer is length of the frame (PHR). The following bytes contain the frame
* itself (PSDU). The length byte (PHR) includes FCS. FCS is already verified by
* the hardware and may be modified by the hardware.
* the buffer is length of the frame (PHR). The following bytes contain the
* frame itself (PSDU). The length byte (PHR) includes FCS. FCS is already
* verified by the hardware and may be modified by the hardware.
* @param[in] power RSSI of received frame.
* @param[in] lqi LQI of received frame.
* @param[in] time Timestamp taken when the last symbol of the frame was received (in us).
@@ -495,12 +508,13 @@ extern void nrf_802154_received_timestamp_raw(uint8_t * p_data,
* This functions works like @ref nrf_802154_received and adds a timestamp to the parameter list.
*
* @note @p timestamp may be inaccurate due to software latency (IRQ handling).
* @note @p timestamp granularity depends on the granularity of the timer driver in the platform/timer
* directory.
* @note Including the timestamp for received frames uses resources like CPU time and memory. If the timestamp
* is not required, use @ref nrf_802154_received instead.
* @note @p timestamp granularity depends on the granularity of the timer driver in the
* platform/timer directory.
* @note Including the timestamp for received frames uses resources like CPU time and memory. If the
* timestamp is not required, use @ref nrf_802154_received instead.
*
* @param[in] p_data Pointer to the buffer containing the payload of the received frame (PSDU without FCS).
* @param[in] p_data Pointer to the buffer containing the payload of the received frame (PSDU
* without FCS).
* @param[in] length Length of received payload.
* @param[in] power RSSI of received frame.
* @param[in] lqi LQI of received frame.
@@ -539,19 +553,19 @@ extern void nrf_802154_tx_started(const uint8_t * p_frame);
/**
* @brief Notify that a frame was transmitted.
*
* @note If ACK was requested for the transmitted frame, this function is called after a proper ACK is
* received. If ACK was not requested, this function is called just after transmission has
* @note If ACK was requested for the transmitted frame, this function is called after a proper ACK
* is received. If ACK was not requested, this function is called just after transmission has
* ended.
* @note The buffer pointed to by @p p_ack is not modified by the radio driver (and cannot
* be used to receive a frame) until @ref nrf_802154_buffer_free_raw is called.
* @note The buffer pointed to by @p p_ack is not modified by the radio driver (and cannot be used
* to receive a frame) until @ref nrf_802154_buffer_free_raw is called.
* @note The buffer pointed to by @p p_ack may be modified by the function handler (and other
* modules) until @ref nrf_802154_buffer_free_raw is called.
*
* @param[in] p_frame Pointer to the buffer containing PHR and PSDU of the transmitted frame.
* @param[in] p_ack Pointer to the received ACK buffer. First byte in the buffer is the length of the
* frame (PHR). The following bytes contain the ACK frame itself (PSDU). The length byte
* (PHR) includes FCS. FCS is already verified by the hardware and may be
* modified by the hardware.
* @param[in] p_ack Pointer to the received ACK buffer. First byte in the buffer is the length
* of the frame (PHR). The following bytes contain the ACK frame itself (PSDU).
* The length byte (PHR) includes FCS. FCS is already verified by the hardware
* and may be modified by the hardware.
* If ACK was not requested, @p p_ack is set to NULL.
* @param[in] power RSSI of received frame or 0 if ACK was not requested.
* @param[in] lqi LQI of received frame or 0 if ACK was not requested.
@@ -566,8 +580,8 @@ extern void nrf_802154_transmitted_raw(const uint8_t * p_frame,
/**
* @brief Notify that a frame was transmitted.
*
* @note If ACK was requested for the transmitted frame, this function is called after a proper ACK is
* received. If ACK was not requested, this function is called just after transmission has
* @note If ACK was requested for the transmitted frame, this function is called after a proper ACK
* is received. If ACK was not requested, this function is called just after transmission has
* ended.
* @note The buffer pointed to by @p p_ack is not modified by the radio driver (and cannot
* be used to receive a frame) until @ref nrf_802154_buffer_free is
@@ -578,8 +592,9 @@ extern void nrf_802154_transmitted_raw(const uint8_t * p_frame,
* @ref nrf_802154_transmitted_raw. It should not handle both functions.
*
* @param[in] p_frame Pointer to the buffer containing PSDU of the transmitted frame.
* @param[in] p_ack Pointer to the buffer containing the received ACK payload (PHR excluding FCS).
* If ACK was not requested, @p p_ack is set to NULL.
* @param[in] p_ack Pointer to the buffer containing the received ACK payload (PHR excluding
* FCS).
* If ACK was not requested, @p p_ack is set to NULL.
* @param[in] length Length of the received ACK payload or 0 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 or 0 if ACK was not requested.
@@ -602,16 +617,16 @@ extern void nrf_802154_transmitted(const uint8_t * p_frame,
* list.
*
* @note @p timestamp may be inaccurate due to software latency (IRQ handling).
* @note @p timestamp granularity depends on the granularity of the timer driver in the platform/timer
* directory.
* @note Including a timestamp for received frames uses resources like CPU time and memory. If the timestamp
* is not required, use @ref nrf_802154_received instead.
* @note @p timestamp granularity depends on the granularity of the timer driver in the
* platform/timer directory.
* @note Including a timestamp for received frames uses resources like CPU time and memory. If the
* timestamp is not required, use @ref nrf_802154_received instead.
*
* @param[in] p_frame Pointer to the buffer containing PSDU of the transmitted frame.
* @param[in] p_ack Pointer to the received ACK buffer. First byte in the buffer is the length of the
* frame (PHR). The following bytes contain the ACK frame itself (PSDU). The length byte
* (PHR) includes FCS. FCS is already verified by the hardware and may be
* modified by the hardware.
* @param[in] p_ack Pointer to the received ACK buffer. First byte in the buffer is the length
* of the frame (PHR). The following bytes contain the ACK frame itself (PSDU).
* The length byte (PHR) includes FCS. FCS is already verified by the hardware
* and may be modified by the hardware.
* If ACK was not requested, @p p_ack is set to NULL.
* @param[in] power RSSI of received frame or 0 if ACK was not requested.
* @param[in] lqi LQI of received frame or 0 if ACK was not requested.
@@ -635,8 +650,8 @@ extern void nrf_802154_transmitted_timestamp_raw(const uint8_t * p_frame,
* @note @p timestamp may be inaccurate due to software latency (IRQ handling).
* @note @p timestamp granularity depends on the granularity of the timer driver in the platform/timer
* directory.
* @note Including a timestamp for received frames uses resources like CPU time and memory. If the timestamp
* is not required, use @ref nrf_802154_received instead.
* @note Including a timestamp for received frames uses resources like CPU time and memory. If the
* timestamp is not required, use @ref nrf_802154_received instead.
*
* @param[in] p_frame Pointer to the buffer containing PSDU of the transmitted frame.
* @param[in] p_ack Pointer to the buffer containing the received ACK payload (PHR excluding FCS).
@@ -713,24 +728,60 @@ extern void nrf_802154_cca_failed(nrf_802154_cca_error_t error);
* @brief Notify the driver that the buffer containing the received frame is not used anymore.
*
* @note The buffer pointed to by @p p_data may be modified by this function.
* @note This function can be safely called only from the main context. To free the buffer from
* a callback or IRQ context, use @ref nrf_802154_buffer_free_immediately_raw.
*
* @param[in] p_data A pointer to the buffer containing the received data that is no longer needed by
* the higher layer.
* @param[in] p_data A pointer to the buffer containing the received data that is no longer needed
* by the higher layer.
*/
void nrf_802154_buffer_free_raw(uint8_t * p_data);
/**
* @brief Notify the driver that the buffer containing the received frame is not used anymore.
*
* @note The buffer pointed to by @p p_data may be modified by this function.
* @note This function can be safely called from any context. If the driver is busy processing
* a request called from a context with lower priority, this function returns false and
* the caller should free the buffer later.
*
* @param[in] p_data A pointer to the buffer containing the received data that is no longer needed
* by the higher layer.
*
* @retval true Buffer was freed successfully.
* @retval false Buffer cannot be freed right now due to ongoing operation.
*/
bool nrf_802154_buffer_free_immediately_raw(uint8_t * p_data);
#else // NRF_802154_USE_RAW_API
/**
* @brief Notify the driver that the buffer containing the received frame is not used anymore.
*
* @note The buffer pointed to by @p p_data may be modified by this function.
* @note This function can be safely called only from the main context. To free the buffer from
* a callback or IRQ context, use @ref nrf_802154_buffer_free_immediately.
*
* @param[in] p_data A pointer to the buffer containing the received data that is no longer needed by
* the higher layer.
* @param[in] p_data A pointer to the buffer containing the received data that is no longer needed
* by the higher layer.
*/
void nrf_802154_buffer_free(uint8_t * p_data);
/**
* @brief Notify the driver that the buffer containing the received frame is not used anymore.
*
* @note The buffer pointed to by @p p_data may be modified by this function.
* @note This function can be safely called from any context. If the driver is busy processing
* a request called from a context with lower priority, this function returns false and
* the caller should free the buffer later.
*
* @param[in] p_data A pointer to the buffer containing the received data that is no longer needed
* by the higher layer.
*
* @retval true Buffer was freed successfully.
* @retval false Buffer cannot be freed right now due to ongoing operation.
*/
bool nrf_802154_buffer_free_immediately(uint8_t * p_data);
#endif // NRF_802154_USE_RAW_API
@@ -771,8 +822,9 @@ int8_t nrf_802154_rssi_last_get(void);
*
* In promiscuous mode, the driver notifies the higher layer that it received any frame (regardless
* frame type or destination address).
* In normal mode (not promiscuous), the higher layer is not notified about ACK frames and frames with
* unknown type. Also frames with a destination address not matching the device address are ignored.
* In normal mode (not promiscuous), the higher layer is not notified about ACK frames and frames
* with unknown type. Also frames with a destination address not matching the device address are
* ignored.
*
* @param[in] enabled If promiscuous mode should be enabled.
*/
@@ -799,13 +851,13 @@ bool nrf_802154_promiscuous_get(void);
* @note Auto ACK is enabled by default.
*
* If auto ACK is enabled, the driver prepares and sends ACK frames automatically
* aTurnaroundTime (192 us) after the proper frame is received. The driver sets the sequence number in
* the ACK frame and a pending bit according to the auto pending bit feature settings. When auto ACK
* is enabled, the driver notifies the next higher layer about the received frame after the ACK
* aTurnaroundTime (192 us) after the proper frame is received. The driver sets the sequence number
* in the ACK frame and a pending bit according to the auto pending bit feature settings. When auto
* ACK is enabled, the driver notifies the next higher layer about the received frame after the ACK
* frame is transmitted.
* If auto ACK is disabled, the driver does not transmit ACK frames. It notifies the next
* higher layer about received frames when a frame is received. In this mode, the next higher layer
* is responsible for sending the ACK frame. ACK frames should be sent using @ref nrf_802154_transmit.
* If auto ACK is disabled, the driver does not transmit ACK frames. It notifies the next higher
* layer about received frames when a frame is received. In this mode, the next higher layer is
* responsible for sending the ACK frame. ACK frames should be sent using @ref nrf_802154_transmit.
*
* @param[in] enabled If auto ACK should be enabled.
*/
@@ -824,13 +876,14 @@ bool nrf_802154_auto_ack_get(void);
*
* @note Setting a pending bit in automatically transmitted ACK frames is enabled by default.
*
* The radio driver automatically sends ACK frames in response frames destined to this node with the ACK
* Request bit set. The pending bit in the ACK frame can be set or cleared regarding data in the indirect queue
* destined to ACK destination.
* The radio driver automatically sends ACK frames in response frames destined to this node with the
* ACK Request bit set. The pending bit in the ACK frame can be set or cleared regarding data in the
* indirect queue destined to ACK destination.
*
* If setting a pending bit in ACK frames is disabled, the pending bit in every ACK frame is set.
* If setting a pending bit in ACK frames is enabled, the radio driver checks if there is data
* in the indirect queue destined to ACK destination. If there is no such data, the pending bit is cleared.
* in the indirect queue destined to ACK destination. If there is no such data, the pending bit is
* cleared.
*
* @note Due to ISR latency, the radio driver might not be able to verify if there is data in
* the indirect queue before ACK is sent. In this case, the pending bit is set.
@@ -866,7 +919,8 @@ bool nrf_802154_pending_bit_for_addr_clear(const uint8_t *p_addr, bool extended)
/**
* @brief Remove all addresses of a given type from the pending bit list.
*
* @param[in] extended If the function should remove all extended MAC addresses or all short addresses.
* @param[in] extended If the function should remove all extended MAC addresses or all short
* addresses.
*/
void nrf_802154_pending_bit_for_addr_reset(bool extended);
@@ -905,14 +959,15 @@ void nrf_802154_cca_cfg_get(nrf_802154_cca_cfg_t * p_cca_cfg);
* The end of the CSMA-CA procedure is notified by @ref nrf_802154_transmitted_raw or
* @ref nrf_802154_transmit_failed.
*
* @note The driver may be configured to automatically time out waiting for an ACK frame depending on
* @ref NRF_802154_ACK_TIMEOUT_ENABLED. If automatic ACK time-out is
* disabled, the CSMA-CA procedure does not time out waiting for an ACK frame if a frame with the ACK
* request bit set was transmitted. The MAC layer should manage the timer to time out waiting for the ACK
* frame. This timer can be started by @ref nrf_802154_tx_started. When the timer
* expires, the MAC layer should call @ref nrf_802154_receive or @ref nrf_802154_sleep to stop
* waiting for the ACK frame.
* @note Before the CSMA-CA procedure is used, the application should initialize a random seed with srand.
* @note The driver may be configured to automatically time out waiting for an ACK frame depending
* on @ref NRF_802154_ACK_TIMEOUT_ENABLED. If automatic ACK time-out is disabled, the CSMA-CA
* procedure does not time out waiting for an ACK frame if a frame with the ACK request bit
* set was transmitted. The MAC layer should manage the timer to time out waiting for the ACK
* frame. This timer can be started by @ref nrf_802154_tx_started. When the timer expires,
* the MAC layer should call @ref nrf_802154_receive or @ref nrf_802154_sleep to stop waiting
* for the ACK frame.
* @note Before the CSMA-CA procedure is used, the application should initialize a random seed with
* srand.
*
* @param[in] p_data Pointer to the frame to transmit. See also @ref nrf_802154_transmit_raw.
*/
@@ -926,14 +981,15 @@ void nrf_802154_transmit_csma_ca_raw(const uint8_t * p_data);
* The end of the CSMA-CA procedure is notified by @ref nrf_802154_transmitted or
* @ref nrf_802154_transmit_failed.
*
* @note The driver may be configured to automatically time out waiting for an ACK frame depending on
* @ref NRF_802154_ACK_TIMEOUT_ENABLED. If automatic ACK time-out is
* disabled, the CSMA-CA procedure does not time out waiting for an ACK frame if a frame with the ACK
* request bit set was transmitted. The MAC layer should manage the timer to time out waiting for the ACK
* frame. This timer can be started by @ref nrf_802154_tx_started. When the timer
* expires, the MAC layer should call @ref nrf_802154_receive or @ref nrf_802154_sleep to stop
* waiting for the ACK frame.
* @note Before the CSMA-CA procedure is used, the application should initialize a random seed with srand.
* @note The driver may be configured to automatically time out waiting for an ACK frame depending
* on @ref NRF_802154_ACK_TIMEOUT_ENABLED. If automatic ACK time-out is disabled, the CSMA-CA
* procedure does not time out waiting for an ACK frame if a frame with the ACK request bit
* set was transmitted. The MAC layer should manage the timer to time out waiting for the ACK
* frame. This timer can be started by @ref nrf_802154_tx_started. When the timer expires,
* the MAC layer should call @ref nrf_802154_receive or @ref nrf_802154_sleep to stop waiting
* for the ACK frame.
* @note Before the CSMA-CA procedure is used, the application should initialize a random seed with
* srand.
*
* @param[in] p_data Pointer to the frame to transmit. See also @ref nrf_802154_transmit.
* @param[in] length Length of the given frame. See also @ref nrf_802154_transmit.
@@ -180,6 +180,7 @@ static uint32_t m_ed_time_left; ///< Remaining time of curren
static uint8_t m_ed_result; ///< Result of current energy detection procedure.
static volatile radio_state_t m_state = RADIO_STATE_SLEEP; ///< State of the radio driver
static volatile bool m_timeslot_is_granted; ///< Indicates if RAAL reported that timeslot is granted.
typedef struct
{
@@ -251,14 +252,32 @@ static uint8_t lqi_get(const uint8_t * p_data)
return (uint8_t)lqi;
}
/** Notify MAC layer that a frame was received. */
/** Check if RAAL reported that timeslot is granted.
*
* @note This function may return other value than @ref nrf_raal_timeslot_is_granted, because
* in critical sections RAAL reports are delayed.
*
* @retval true RAAL reported that timeslot is granted.
* @retval false RAAL reported that timeslot is not granted.
*/
static bool timeslot_is_granted(void)
{
return m_timeslot_is_granted;
}
static void received_frame_notify(uint8_t * p_psdu)
{
nrf_802154_critical_section_nesting_allow();
nrf_802154_notify_received(p_psdu, // data
rssi_last_measurement_get(), // rssi
lqi_get(p_psdu)); // lqi
}
/** Allow nesting critical sections and notify MAC layer that a frame was received. */
static void received_frame_notify_and_nesting_allow(uint8_t * p_psdu)
{
nrf_802154_critical_section_nesting_allow();
received_frame_notify(p_psdu);
nrf_802154_critical_section_nesting_deny();
}
@@ -610,7 +629,7 @@ static bool ed_iter_setup(uint32_t time_us)
}
else
{
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
irq_deinit();
nrf_radio_reset();
@@ -857,12 +876,19 @@ static void rx_restart(bool set_shorts)
/** Terminate Falling Asleep procedure. */
static void falling_asleep_terminate(void)
{
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
nrf_radio_int_disable(NRF_RADIO_INT_DISABLED_MASK);
}
}
/** Terminate Sleep procedure. */
static void sleep_terminate(void)
{
nrf_802154_priority_drop_timeslot_exit_terminate();
nrf_raal_continuous_mode_enter();
}
/** Terminate RX procedure. */
static void rx_terminate(void)
{
@@ -898,7 +924,7 @@ static void rx_terminate(void)
nrf_timer_shorts_disable(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE1_STOP_MASK);
#endif // NRF_802154_DISABLE_BCC_MATCHING
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
#if !NRF_802154_DISABLE_BCC_MATCHING || NRF_802154_NOTIFY_CRCERROR
ints_to_disable |= NRF_RADIO_INT_CRCERROR_MASK;
@@ -943,7 +969,7 @@ static void tx_ack_terminate(void)
nrf_timer_shorts_disable(NRF_802154_COUNTER_TIMER_INSTANCE, NRF_TIMER_SHORT_COMPARE1_STOP_MASK);
#endif // NRF_802154_DISABLE_BCC_MATCHING
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
ints_to_disable = nrf_802154_revision_has_phyend_event() ?
NRF_RADIO_INT_PHYEND_MASK : NRF_RADIO_INT_END_MASK;
@@ -970,7 +996,7 @@ static void tx_terminate(void)
nrf_ppi_channel_remove_from_group(PPI_EGU_RAMP_UP, PPI_CHGRP0);
nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0);
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
ints_to_disable = nrf_802154_revision_has_phyend_event() ?
NRF_RADIO_INT_PHYEND_MASK : NRF_RADIO_INT_END_MASK;
@@ -996,7 +1022,7 @@ static void rx_ack_terminate(void)
nrf_ppi_channel_remove_from_group(PPI_EGU_RAMP_UP, PPI_CHGRP0);
nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0);
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
nrf_radio_int_disable(NRF_RADIO_INT_END_MASK);
nrf_radio_shorts_set(SHORTS_IDLE);
@@ -1017,7 +1043,7 @@ static void ed_terminate(void)
nrf_ppi_channel_remove_from_group(PPI_EGU_RAMP_UP, PPI_CHGRP0);
nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0);
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
nrf_radio_int_disable(NRF_RADIO_INT_EDEND_MASK);
nrf_radio_shorts_set(SHORTS_IDLE);
@@ -1036,7 +1062,7 @@ static void cca_terminate(void)
nrf_ppi_channel_remove_from_group(PPI_EGU_RAMP_UP, PPI_CHGRP0);
nrf_ppi_fork_endpoint_setup(PPI_EGU_RAMP_UP, 0);
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
nrf_radio_int_disable(NRF_RADIO_INT_CCABUSY_MASK | NRF_RADIO_INT_CCAIDLE_MASK);
nrf_radio_shorts_set(SHORTS_IDLE);
@@ -1052,7 +1078,7 @@ static void continuous_carrier_terminate(void)
fem_for_pa_reset();
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE);
}
@@ -1085,9 +1111,8 @@ static bool current_operation_terminate(nrf_802154_term_t term_lvl,
case RADIO_STATE_SLEEP:
if (req_orig != REQ_ORIG_RAAL)
{
// Enter continuous mode unless terminating current operation is requested by
// RAAL during timeslot end procedure.
nrf_raal_continuous_mode_enter();
// Terminate sleep state unless it is requested by RAAL during timeslot end.
sleep_terminate();
}
break;
@@ -1124,6 +1149,12 @@ static bool current_operation_terminate(nrf_802154_term_t term_lvl,
if (term_lvl >= NRF_802154_TERM_802154)
{
tx_ack_terminate();
if (notify_abort)
{
mp_current_rx_buffer->free = false;
received_frame_notify(mp_current_rx_buffer->psdu);
}
}
else
{
@@ -1216,12 +1247,13 @@ static bool current_operation_terminate(nrf_802154_term_t term_lvl,
static void sleep_init(void)
{
nrf_802154_priority_drop_timeslot_exit();
m_timeslot_is_granted = false;
}
/** Initialize Falling Asleep operation. */
static void falling_asleep_init(void)
{
if (!nrf_raal_timeslot_is_granted())
if (!timeslot_is_granted())
{
state_set(RADIO_STATE_SLEEP);
sleep_init();
@@ -1248,7 +1280,7 @@ static void rx_init(bool disabled_was_triggered)
uint32_t lna_target_time;
uint32_t pa_target_time;
if (!nrf_raal_timeslot_is_granted())
if (!timeslot_is_granted())
{
return;
}
@@ -1532,7 +1564,7 @@ static void cca_init(bool disabled_was_triggered)
/** Initialize Continuous Carrier operation. */
static void continuous_carrier_init(bool disabled_was_triggered)
{
if (!nrf_raal_timeslot_is_granted())
if (!timeslot_is_granted())
{
return;
}
@@ -1568,6 +1600,11 @@ void nrf_raal_timeslot_started(void)
nrf_radio_init();
irq_init();
if (m_state != RADIO_STATE_SLEEP)
{
m_timeslot_is_granted = true;
}
assert(nrf_radio_shorts_get() == SHORTS_IDLE);
switch (m_state)
@@ -1628,6 +1665,9 @@ void nrf_raal_timeslot_ended(void)
result = current_operation_terminate(NRF_802154_TERM_802154, REQ_ORIG_RAAL, false);
assert(result);
(void)result;
m_timeslot_is_granted = false;
switch (m_state)
{
@@ -1650,7 +1690,8 @@ void nrf_raal_timeslot_ended(void)
case RADIO_STATE_TX_ACK:
state_set(RADIO_STATE_RX);
receive_failed_notify(NRF_802154_RX_ERROR_TIMESLOT_ENDED);
mp_current_rx_buffer->free = false;
received_frame_notify_and_nesting_allow(mp_current_rx_buffer->psdu);
break;
case RADIO_STATE_CCA_TX:
@@ -1823,7 +1864,7 @@ static void irq_crcok_state_rx(void)
nrf_802154_pib_promiscuous_get())
{
mp_current_rx_buffer->free = false;
received_frame_notify(p_received_psdu);
received_frame_notify_and_nesting_allow(p_received_psdu);
}
return;
@@ -1941,7 +1982,7 @@ static void irq_crcok_state_rx(void)
rx_terminate();
rx_init(true);
received_frame_notify(p_received_psdu);
received_frame_notify_and_nesting_allow(p_received_psdu);
}
}
else
@@ -1967,7 +2008,7 @@ static void irq_crcok_state_rx(void)
}
}
received_frame_notify(p_received_psdu);
received_frame_notify_and_nesting_allow(p_received_psdu);
}
else
{
@@ -2101,7 +2142,7 @@ static void irq_phyend_state_tx_ack(void)
rx_flags_clear();
received_frame_notify(p_received_psdu);
received_frame_notify_and_nesting_allow(p_received_psdu);
}
static void irq_phyend_state_tx_frame(void)
@@ -2545,7 +2586,7 @@ void nrf_802154_core_deinit(void)
{
current_operation_terminate(NRF_802154_TERM_802154, REQ_ORIG_HIGHER_LAYER, true);
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
nrf_radio_reset();
}
@@ -2681,7 +2722,7 @@ bool nrf_802154_core_notify_buffer_free(uint8_t * p_data)
p_buffer->free = true;
if (!nrf_raal_timeslot_is_granted())
if (!timeslot_is_granted())
{
return true;
}
@@ -2734,7 +2775,7 @@ bool nrf_802154_core_channel_update(void)
{
bool result;
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
channel_set(nrf_802154_pib_channel_get());
}
@@ -2750,7 +2791,7 @@ bool nrf_802154_core_channel_update(void)
}
case RADIO_STATE_CONTINUOUS_CARRIER:
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
channel_set(nrf_802154_pib_channel_get());
nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE);
@@ -2763,7 +2804,7 @@ bool nrf_802154_core_channel_update(void)
case RADIO_STATE_TX:
case RADIO_STATE_RX_ACK:
case RADIO_STATE_CCA:
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
channel_set(nrf_802154_pib_channel_get());
}
@@ -2782,7 +2823,7 @@ bool nrf_802154_core_channel_update(void)
bool nrf_802154_core_cca_cfg_update(void)
{
if (nrf_raal_timeslot_is_granted())
if (timeslot_is_granted())
{
cca_configuration_update();
}
@@ -149,6 +149,7 @@ void nrf_802154_critical_section_forcefully_enter(void)
{
bool critical_section_entered = critical_section_enter(true);
assert(critical_section_entered);
(void)critical_section_entered;
}
void nrf_802154_critical_section_exit(void)
@@ -167,6 +168,7 @@ void nrf_802154_critical_section_exit(void)
if (cnt == 1)
{
assert(!exiting_crit_sect);
(void)exiting_crit_sect;
exiting_crit_sect = true;
// RAAL critical section shall be exited before RADIO IRQ handler is enabled. In other
@@ -55,6 +55,15 @@ void nrf_802154_priority_drop_init(void);
*/
void nrf_802154_priority_drop_timeslot_exit(void);
/**
* @brief Terminate requesting of timeslot discarding.
*
* Function used to to terminate timeslot exit procedure requested by previous call to
* @rev nrf_802154_priority_drop_timeslot_exit. Timeslot discarding is terminated only if it has
* not been started.
*/
void nrf_802154_priority_drop_timeslot_exit_terminate(void);
/**
*@}
**/
@@ -49,3 +49,9 @@ void nrf_802154_priority_drop_timeslot_exit(void)
nrf_raal_continuous_mode_exit();
}
void nrf_802154_priority_drop_timeslot_exit_terminate(void)
{
// Intentionally empty:
// nrf_802154_priority_drop_timeslot_exit is synchronous and cannot be terminated.
}
@@ -49,3 +49,8 @@ void nrf_802154_priority_drop_timeslot_exit(void)
nrf_802154_swi_timeslot_exit();
}
void nrf_802154_priority_drop_timeslot_exit_terminate(void)
{
nrf_802154_swi_timeslot_exit_terminate();
}
@@ -43,39 +43,25 @@
#include "nrf_802154_critical_section.h"
#include "hal/nrf_radio.h"
#define REQUEST_FUNCTION(func_core, params_core) \
#define REQUEST_FUNCTION_WITH_FAIL_INSTR(func_core, fail_instr, ...) \
bool result; \
\
if (nrf_802154_critical_section_enter()) \
{ \
result = func_core params_core; \
result = func_core(__VA_ARGS__); \
nrf_802154_critical_section_exit(); \
} \
else \
{ \
fail_instr \
result = false; \
} \
\
return result;
#define REQUEST_FUNCTION(func_core, ...) \
REQUEST_FUNCTION_WITH_FAIL_INSTR(func_core, , __VA_ARGS__)
#define REQUEST_FUNCTION_NO_ARGS(func_core) \
REQUEST_FUNCTION(func_core, ())
#define REQUEST_FUNCTION_1_ARG(func_core, arg) \
REQUEST_FUNCTION(func_core, (arg))
#define REQUEST_FUNCTION_2_ARGS(func_core, arg1, arg2) \
REQUEST_FUNCTION(func_core, (arg1, arg2))
#define REQUEST_FUNCTION_3_ARGS(func_core, arg1, arg2, arg3) \
REQUEST_FUNCTION(func_core, (arg1, arg2, arg3))
#define REQUEST_FUNCTION_4_ARGS(func_core, arg1, arg2, arg3, arg4) \
REQUEST_FUNCTION(func_core, (arg1, arg2, arg3, arg4))
#define REQUEST_FUNCTION_5_ARGS(func_core, arg1, arg2, arg3, arg4, arg5) \
REQUEST_FUNCTION(func_core, (arg1, arg2, arg3, arg4, arg5))
void nrf_802154_request_init(void)
{
@@ -84,14 +70,18 @@ void nrf_802154_request_init(void)
bool nrf_802154_request_sleep(nrf_802154_term_t term_lvl)
{
REQUEST_FUNCTION_1_ARG(nrf_802154_core_sleep, term_lvl)
REQUEST_FUNCTION(nrf_802154_core_sleep, term_lvl)
}
bool nrf_802154_request_receive(nrf_802154_term_t term_lvl,
req_originator_t req_orig,
nrf_802154_notification_func_t notify_function)
{
REQUEST_FUNCTION_3_ARGS(nrf_802154_core_receive, term_lvl, req_orig, notify_function)
REQUEST_FUNCTION_WITH_FAIL_INSTR(nrf_802154_core_receive,
notify_function(false); ,
term_lvl,
req_orig,
notify_function)
}
bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl,
@@ -100,40 +90,41 @@ bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl,
bool cca,
nrf_802154_notification_func_t notify_function)
{
REQUEST_FUNCTION_5_ARGS(nrf_802154_core_transmit,
term_lvl,
req_orig,
p_data,
cca,
notify_function)
REQUEST_FUNCTION_WITH_FAIL_INSTR(nrf_802154_core_transmit,
notify_function(false); ,
term_lvl,
req_orig,
p_data,
cca,
notify_function)
}
bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl, uint32_t time_us)
{
REQUEST_FUNCTION_2_ARGS(nrf_802154_core_energy_detection, term_lvl, time_us)
REQUEST_FUNCTION(nrf_802154_core_energy_detection, term_lvl, time_us)
}
bool nrf_802154_request_cca(nrf_802154_term_t term_lvl)
{
REQUEST_FUNCTION_1_ARG(nrf_802154_core_cca, term_lvl)
REQUEST_FUNCTION(nrf_802154_core_cca, term_lvl)
}
bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl)
{
REQUEST_FUNCTION_1_ARG(nrf_802154_core_continuous_carrier, term_lvl)
REQUEST_FUNCTION(nrf_802154_core_continuous_carrier, term_lvl)
}
bool nrf_802154_request_buffer_free(uint8_t * p_data)
{
REQUEST_FUNCTION_1_ARG(nrf_802154_core_notify_buffer_free, p_data)
REQUEST_FUNCTION(nrf_802154_core_notify_buffer_free, p_data)
}
bool nrf_802154_request_channel_update(void)
{
REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_channel_update)
REQUEST_FUNCTION(nrf_802154_core_channel_update)
}
bool nrf_802154_request_cca_cfg_update(void)
{
REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_cca_cfg_update)
REQUEST_FUNCTION(nrf_802154_core_cca_cfg_update)
}
@@ -50,14 +50,40 @@
#include <nrf.h>
#define REQUEST_FUNCTION(func_core, params_core, func_swi, params_swi) \
#define REQUEST_FUNCTION_WITH_FAIL_INSTR(func_core, func_swi, fail_instr, ...) \
bool result = false; \
\
if (active_vector_priority_is_high()) \
{ \
if (nrf_802154_critical_section_enter()) \
{ \
result = func_core params_core; \
result = func_core(__VA_ARGS__); \
nrf_802154_critical_section_exit(); \
} \
else \
{ \
fail_instr \
result = false; \
} \
} \
else \
{ \
func_swi(__VA_ARGS__, &result); \
} \
\
return result;
#define REQUEST_FUNCTION(func_core, func_swi, ...) \
REQUEST_FUNCTION_WITH_FAIL_INSTR(func_core, func_swi, , __VA_ARGS__)
#define REQUEST_FUNCTION_NO_ARGS(func_core, func_swi) \
bool result = false; \
\
if (active_vector_priority_is_high()) \
{ \
if (nrf_802154_critical_section_enter()) \
{ \
result = func_core(); \
nrf_802154_critical_section_exit(); \
} \
else \
@@ -67,35 +93,11 @@
} \
else \
{ \
func_swi params_swi; \
func_swi(&result); \
} \
\
return result;
#define REQUEST_FUNCTION_NO_ARGS(func_core, func_swi) \
REQUEST_FUNCTION(func_core, (), func_swi, (&result))
#define REQUEST_FUNCTION_1_ARG(func_core, func_swi, arg) \
REQUEST_FUNCTION(func_core, (arg), func_swi, (arg, &result))
#define REQUEST_FUNCTION_2_ARGS(func_core, func_swi, arg1, arg2) \
REQUEST_FUNCTION(func_core, (arg1, arg2), func_swi, (arg1, arg2, &result))
#define REQUEST_FUNCTION_3_ARGS(func_core, func_swi, arg1, arg2, arg3) \
REQUEST_FUNCTION(func_core, (arg1, arg2, arg3), func_swi, (arg1, arg2, arg3, &result))
#define REQUEST_FUNCTION_4_ARGS(func_core, func_swi, arg1, arg2, arg3, arg4) \
REQUEST_FUNCTION(func_core, \
(arg1, arg2, arg3, arg4), \
func_swi, \
(arg1, arg2, arg3, arg4, &result))
#define REQUEST_FUNCTION_5_ARGS(func_core, func_swi, arg1, arg2, arg3, arg4, arg5) \
REQUEST_FUNCTION(func_core, \
(arg1, arg2, arg3, arg4, arg5), \
func_swi, \
(arg1, arg2, arg3, arg4, arg5, &result))
/** Check if active vector priority is high enough to call requests directly.
*
* @retval true Active vector priority is greater or equal to SWI priority.
@@ -114,20 +116,19 @@ void nrf_802154_request_init(void)
bool nrf_802154_request_sleep(nrf_802154_term_t term_lvl)
{
REQUEST_FUNCTION_1_ARG(nrf_802154_core_sleep,
nrf_802154_swi_sleep,
term_lvl)
REQUEST_FUNCTION(nrf_802154_core_sleep, nrf_802154_swi_sleep, term_lvl)
}
bool nrf_802154_request_receive(nrf_802154_term_t term_lvl,
req_originator_t req_orig,
nrf_802154_notification_func_t notify_function)
{
REQUEST_FUNCTION_3_ARGS(nrf_802154_core_receive,
nrf_802154_swi_receive,
term_lvl,
req_orig,
notify_function)
REQUEST_FUNCTION_WITH_FAIL_INSTR(nrf_802154_core_receive,
nrf_802154_swi_receive,
notify_function(false); ,
term_lvl,
req_orig,
notify_function)
}
bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl,
@@ -136,54 +137,47 @@ bool nrf_802154_request_transmit(nrf_802154_term_t term_lvl,
bool cca,
nrf_802154_notification_func_t notify_function)
{
REQUEST_FUNCTION_5_ARGS(nrf_802154_core_transmit,
nrf_802154_swi_transmit,
term_lvl,
req_orig,
p_data,
cca,
notify_function)
REQUEST_FUNCTION_WITH_FAIL_INSTR(nrf_802154_core_transmit,
nrf_802154_swi_transmit,
notify_function(false); ,
term_lvl,
req_orig,
p_data,
cca,
notify_function)
}
bool nrf_802154_request_energy_detection(nrf_802154_term_t term_lvl,
uint32_t time_us)
{
REQUEST_FUNCTION_2_ARGS(nrf_802154_core_energy_detection,
nrf_802154_swi_energy_detection,
term_lvl,
time_us)
REQUEST_FUNCTION(nrf_802154_core_energy_detection,
nrf_802154_swi_energy_detection,
term_lvl,
time_us)
}
bool nrf_802154_request_cca(nrf_802154_term_t term_lvl)
{
REQUEST_FUNCTION_1_ARG(nrf_802154_core_cca,
nrf_802154_swi_cca,
term_lvl)
REQUEST_FUNCTION(nrf_802154_core_cca, nrf_802154_swi_cca, term_lvl)
}
bool nrf_802154_request_continuous_carrier(nrf_802154_term_t term_lvl)
{
REQUEST_FUNCTION_1_ARG(nrf_802154_core_continuous_carrier,
nrf_802154_swi_continuous_carrier,
term_lvl)
REQUEST_FUNCTION(nrf_802154_core_continuous_carrier, nrf_802154_swi_continuous_carrier, term_lvl)
}
bool nrf_802154_request_buffer_free(uint8_t * p_data)
{
REQUEST_FUNCTION_1_ARG(nrf_802154_core_notify_buffer_free,
nrf_802154_swi_buffer_free,
p_data)
REQUEST_FUNCTION(nrf_802154_core_notify_buffer_free, nrf_802154_swi_buffer_free, p_data)
}
bool nrf_802154_request_channel_update(void)
{
REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_channel_update,
nrf_802154_swi_channel_update)
REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_channel_update, nrf_802154_swi_channel_update)
}
bool nrf_802154_request_cca_cfg_update(void)
{
REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_cca_cfg_update,
nrf_802154_swi_cca_cfg_update)
REQUEST_FUNCTION_NO_ARGS(nrf_802154_core_cca_cfg_update, nrf_802154_swi_cca_cfg_update)
}
@@ -111,7 +111,7 @@ bool nrf_802154_revision_has_phyend_event(void)
#elif NRF52840_AABA
return true;
#else
bool result;
bool result = false;
switch (m_nrf52840_revision)
{
@@ -368,6 +368,7 @@ static nrf_802154_req_data_t * req_enter(void)
__ISB();
assert(!req_queue_is_full());
(void)req_queue_is_full();
return &m_req_queue[m_req_w_ptr];
}
@@ -511,6 +512,7 @@ void nrf_802154_swi_notify_cca(bool channel_free)
void nrf_802154_swi_notify_cca_failed(nrf_802154_cca_error_t error)
{
assert(!ntf_queue_is_full());
(void)ntf_queue_is_full();
nrf_802154_ntf_data_t * p_slot = &m_ntf_queue[m_ntf_w_ptr];
@@ -529,6 +531,11 @@ void nrf_802154_swi_timeslot_exit(void)
nrf_egu_task_trigger(SWI_EGU, TIMESLOT_EXIT_TASK);
}
void nrf_802154_swi_timeslot_exit_terminate(void)
{
nrf_egu_event_clear(SWI_EGU, TIMESLOT_EXIT_EVENT);
}
void nrf_802154_swi_sleep(nrf_802154_term_t term_lvl, bool * p_result)
{
nrf_802154_req_data_t * p_slot = req_enter();
@@ -754,6 +761,12 @@ void SWI_IRQHandler(void)
p_slot->data.receive.req_orig,
p_slot->data.receive.notif_func) :
false;
if (!in_crit_sect)
{
p_slot->data.receive.notif_func(false);
}
break;
case REQ_TYPE_TRANSMIT:
@@ -764,6 +777,12 @@ void SWI_IRQHandler(void)
p_slot->data.transmit.cca,
p_slot->data.transmit.notif_func) :
false;
if (!in_crit_sect)
{
p_slot->data.transmit.notif_func(false);
}
break;
case REQ_TYPE_ENERGY_DETECTION:
@@ -127,6 +127,13 @@ void nrf_802154_swi_notify_cca_failed(nrf_802154_cca_error_t error);
*/
void nrf_802154_swi_timeslot_exit(void);
/**
* @brief Terminate discarding of the timeslot.
*
* @note This function terminates discrading of timeslot only if it has not been performed.
*/
void nrf_802154_swi_timeslot_exit_terminate(void);
/**
* @brief Request entering sleep state from SWI priority.
*
@@ -44,7 +44,9 @@
#include "platform/clock/nrf_802154_clock.h"
static bool m_continuous;
static bool m_continuous;
static volatile bool m_critical_section;
static volatile bool m_started_pending;
void nrf_raal_init(void)
{
@@ -93,15 +95,28 @@ uint32_t nrf_raal_timeslot_us_left_get(void)
void nrf_raal_critical_section_enter(void)
{
// Intentionally empty.
m_critical_section = true;
}
void nrf_raal_critical_section_exit(void)
{
// Intentionally empty.
m_critical_section = false;
if (m_started_pending)
{
nrf_raal_timeslot_started();
m_started_pending = false;
}
}
void nrf_802154_clock_hfclk_ready(void)
{
nrf_raal_timeslot_started();
if (m_critical_section)
{
m_started_pending = true;
}
else
{
nrf_raal_timeslot_started();
}
}
@@ -689,6 +689,7 @@ void nrf_raal_init(void)
uint32_t err_code = sd_radio_session_open(signal_handler);
assert(err_code == NRF_SUCCESS);
(void)err_code;
m_initialized = true;
}
@@ -699,6 +700,7 @@ void nrf_raal_uninit(void)
uint32_t err_code = sd_radio_session_close();
assert(err_code == NRF_SUCCESS);
(void)err_code;
m_continuous = false;
m_timeslot_state = TIMESLOT_STATE_IDLE;