diff --git a/drivers/at86rf215/Makefile.dep b/drivers/at86rf215/Makefile.dep index 2810697566..d079dfb38f 100644 --- a/drivers/at86rf215/Makefile.dep +++ b/drivers/at86rf215/Makefile.dep @@ -33,3 +33,7 @@ endif USEMODULE += xtimer USEMODULE += ieee802154 USEMODULE += netdev_ieee802154 + +ifneq (,$(filter gnrc_netif_timestamp,$(USEMODULE))) + USEMODULE += at86rf215_timestamp +endif diff --git a/drivers/at86rf215/at86rf215.c b/drivers/at86rf215/at86rf215.c index 6a88d527d4..23c093e3ce 100644 --- a/drivers/at86rf215/at86rf215.c +++ b/drivers/at86rf215/at86rf215.c @@ -150,6 +150,10 @@ if (!IS_ACTIVE(CONFIG_AT86RF215_USE_CLOCK_OUTPUT)){ reg |= AMCS_AACK_MASK; } + if (IS_USED(MODULE_AT86RF215_TIMESTAMP)) { + at86rf215_reg_write(dev, dev->BBC->RG_CNTC, + CNTC_EN_MASK | CNTC_CAPRXS_MASK); + } at86rf215_reg_write(dev, dev->BBC->RG_AMCS, reg); if (CONFIG_AT86RF215_DEFAULT_PHY_MODE == IEEE802154_PHY_OQPSK) { diff --git a/drivers/at86rf215/at86rf215_netdev.c b/drivers/at86rf215/at86rf215_netdev.c index 1582223d2b..07ba4cb0fb 100644 --- a/drivers/at86rf215/at86rf215_netdev.c +++ b/drivers/at86rf215/at86rf215_netdev.c @@ -199,6 +199,16 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) if (info != NULL) { netdev_ieee802154_rx_info_t *radio_info = info; radio_info->rssi = (int8_t) at86rf215_reg_read(dev, dev->RF->RG_EDV); + + if (IS_USED(MODULE_AT86RF215_TIMESTAMP)) { + uint32_t rx_timestamp; + at86rf215_reg_read_bytes(dev, dev->BBC->RG_CNT0, &rx_timestamp, + sizeof(rx_timestamp)); + + /* convert counter value to ns */ + radio_info->timestamp = rx_timestamp * 1000ULL / 32; + radio_info->flags |= NETDEV_RX_IEEE802154_INFO_FLAG_TIMESTAMP; + } } return pkt_len; diff --git a/drivers/include/net/netdev/ieee802154.h b/drivers/include/net/netdev/ieee802154.h index e1a0b4b608..6895ef6532 100644 --- a/drivers/include/net/netdev/ieee802154.h +++ b/drivers/include/net/netdev/ieee802154.h @@ -67,6 +67,13 @@ extern "C" { * @} */ + /** + * @name Flags for use in @ref netdev_ieee802154_rx_info::flags + * @{ + */ +#define NETDEV_RX_IEEE802154_INFO_FLAG_TIMESTAMP (0x01) /**< Timestamp valid */ +/** @} */ + /** * @brief Option parameter to be used with @ref NETOPT_CCA_MODE to set * the mode of the clear channel assessment (CCA) defined @@ -128,7 +135,15 @@ typedef struct { /** * @brief Received packet status information for IEEE 802.15.4 radios */ -typedef struct netdev_radio_rx_info netdev_ieee802154_rx_info_t; +typedef struct netdev_ieee802154_rx_info { + uint64_t timestamp; /**< Timestamp value of a received frame in ns */ + int16_t rssi; /**< RSSI of a received frame in dBm */ + uint8_t lqi; /**< LQI of a received frame */ + uint8_t flags; /**< Flags e.g. used to mark other fields as valid */ +#if IS_USED(MODULE_SOCK_AUX_TIMESTAP) + uint64_t timestamp; /**< Timestamp value of a received frame in ns */ +#endif +} netdev_ieee802154_rx_info_t; /** * @brief Reset function for ieee802154 common fields diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 9e17653459..bc02c3d348 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -4,6 +4,7 @@ PSEUDOMODULES += at_urc_isr_low PSEUDOMODULES += at_urc_isr_medium PSEUDOMODULES += at_urc_isr_highest PSEUDOMODULES += at24c% +PSEUDOMODULES += at86rf215_timestamp PSEUDOMODULES += atomic_utils PSEUDOMODULES += base64url PSEUDOMODULES += board_software_reset diff --git a/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c b/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c index c54f6beb25..d1d324afbe 100644 --- a/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c +++ b/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c @@ -129,6 +129,11 @@ static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) gnrc_netif_hdr_t *hdr = netif_snip->data; hdr->lqi = rx_info.lqi; hdr->rssi = rx_info.rssi; +#if IS_USED(MODULE_GNRC_NETIF_TIMESTAMP) + if (rx_info.flags & NETDEV_RX_IEEE802154_INFO_FLAG_TIMESTAMP) { + gnrc_netif_hdr_set_timestamp(hdr, rx_info.timestamp); + } +#endif gnrc_netif_hdr_set_netif(hdr, netif); pkt = gnrc_pkt_append(pkt, netif_snip); } @@ -198,6 +203,11 @@ static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) #endif hdr->lqi = rx_info.lqi; hdr->rssi = rx_info.rssi; +#if IS_USED(MODULE_GNRC_NETIF_TIMESTAMP) + if (rx_info.flags & NETDEV_RX_IEEE802154_INFO_FLAG_TIMESTAMP) { + gnrc_netif_hdr_set_timestamp(hdr, rx_info.timestamp); + } +#endif gnrc_netif_hdr_set_netif(hdr, netif); dev->driver->get(dev, NETOPT_PROTO, &pkt->type, sizeof(pkt->type)); if (IS_ACTIVE(ENABLE_DEBUG)) { diff --git a/tests/driver_at86rf215/Makefile b/tests/driver_at86rf215/Makefile index f54d6765b5..bdddfa34f0 100644 --- a/tests/driver_at86rf215/Makefile +++ b/tests/driver_at86rf215/Makefile @@ -3,5 +3,6 @@ BOARD ?= openmote-b # the radio driver to test USEMODULE += at86rf215 USEMODULE += at86rf215_batmon +USEMODULE += at86rf215_timestamp include ../driver_netdev_common/Makefile.netdev.mk