diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 530ac346993..7bc8a33a1a1 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -42,7 +42,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include "ieee802154_nrf5.h" #include "nrf_802154.h" -#ifdef CONFIG_NRF_802154_SER_HOST +#if defined(CONFIG_NRF_802154_SER_HOST) #include "nrf_802154_serialization_error.h" #endif @@ -511,6 +511,13 @@ static int nrf5_tx(const struct device *dev, return -EIO; } +static uint64_t nrf5_get_time(const struct device *dev) +{ + ARG_UNUSED(dev); + + return nrf_802154_time_get(); +} + static int nrf5_start(const struct device *dev) { ARG_UNUSED(dev); @@ -803,7 +810,7 @@ void nrf_802154_energy_detection_failed(nrf_802154_ed_error_t error) } } -#ifdef CONFIG_NRF_802154_SER_HOST +#if defined(CONFIG_NRF_802154_SER_HOST) void nrf_802154_serialization_error(const nrf_802154_ser_err_data_t *p_err) { __ASSERT(false, "802.15.4 serialization error"); @@ -826,6 +833,7 @@ static struct ieee802154_radio_api nrf5_radio_api = { .stop = nrf5_stop, .tx = nrf5_tx, .ed_scan = nrf5_energy_scan_start, + .get_time = nrf5_get_time, .configure = nrf5_configure, }; diff --git a/include/net/ieee802154_radio.h b/include/net/ieee802154_radio.h index 48225df7fa5..bd43324732a 100644 --- a/include/net/ieee802154_radio.h +++ b/include/net/ieee802154_radio.h @@ -237,6 +237,9 @@ struct ieee802154_radio_api { int (*ed_scan)(const struct device *dev, uint16_t duration, energy_scan_done_cb_t done_cb); + + /** Get the current radio time in microseconds */ + uint64_t (*get_time)(const struct device *dev); }; /* Make sure that the network interface API is properly setup inside diff --git a/subsys/net/lib/openthread/platform/radio.c b/subsys/net/lib/openthread/platform/radio.c index 8ee412fb8d3..adf965d8bcf 100644 --- a/subsys/net/lib/openthread/platform/radio.c +++ b/subsys/net/lib/openthread/platform/radio.c @@ -257,7 +257,16 @@ void transmit_message(struct k_work *tx_job) radio_api->set_channel(radio_dev, sTransmitFrame.mChannel); radio_api->set_txpower(radio_dev, tx_power); - if (sTransmitFrame.mInfo.mTxInfo.mCsmaCaEnabled) { + if ((radio_api->get_capabilities(radio_dev) & IEEE802154_HW_TXTIME) && + (sTransmitFrame.mInfo.mTxInfo.mTxDelay != 0)) { + uint64_t tx_at = sTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime + + sTransmitFrame.mInfo.mTxInfo.mTxDelay; + net_pkt_set_txtime(tx_pkt, NSEC_PER_USEC * tx_at); + if (radio_api->tx(radio_dev, IEEE802154_TX_MODE_TXTIME_CCA, + tx_pkt, tx_payload)) { + tx_result = OT_ERROR_INVALID_STATE; + } + } else if (sTransmitFrame.mInfo.mTxInfo.mCsmaCaEnabled) { if (radio_api->get_capabilities(radio_dev) & IEEE802154_HW_CSMA) { if (radio_api->tx(radio_dev, IEEE802154_TX_MODE_CSMA_CA, @@ -878,3 +887,10 @@ otError otPlatRadioSetTransmitPower(otInstance *aInstance, int8_t aPower) return OT_ERROR_NONE; } + +uint64_t otPlatRadioGetNow(otInstance *aInstance) +{ + ARG_UNUSED(aInstance); + + return radio_api->get_time(radio_dev); +}