From c52f6e71c2bd088883ab39a009f34740083986d9 Mon Sep 17 00:00:00 2001 From: chudov Date: Tue, 16 May 2023 17:12:10 +0200 Subject: [PATCH] drivers/at86rf2xx: rx timestamp generation for ATmegaRFR2 Signed-off-by: chudov --- cpu/atmega_common/include/cpu_conf.h | 2 + drivers/at86rf2xx/at86rf2xx_netdev.c | 17 +++++++- .../at86rf2xx/include/at86rf2xx_internal.h | 42 +++++++++++++++++++ sys/include/net/gnrc/netif/hdr.h | 1 + sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c | 6 ++- tests/net/gnrc_netif_ieee802154/Makefile | 31 ++++++++++---- tests/net/gnrc_netif_ieee802154/main.c | 18 +++++++- 7 files changed, 106 insertions(+), 11 deletions(-) diff --git a/cpu/atmega_common/include/cpu_conf.h b/cpu/atmega_common/include/cpu_conf.h index 639c6ab751..8cb9dd8560 100644 --- a/cpu/atmega_common/include/cpu_conf.h +++ b/cpu/atmega_common/include/cpu_conf.h @@ -31,7 +31,9 @@ extern "C" { #endif +#ifndef THREAD_EXTRA_STACKSIZE_PRINTF #define THREAD_EXTRA_STACKSIZE_PRINTF (128) +#endif /** * @name Kernel configuration diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index 661243f6cb..5765c55555 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -319,8 +319,23 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) at86rf2xx_fb_stop(dev); #endif radio_info->rssi = RSSI_BASE_VAL + ed; - DEBUG("[at86rf2xx] LQI:%d high is good, RSSI:%d high is either good or" + DEBUG("[at86rf2xx] LQI:%d high is good, RSSI:%d high is either good or " "too much interference.\n", radio_info->lqi, radio_info->rssi); +#if AT86RF2XX_IS_PERIPH && IS_USED(MODULE_NETDEV_IEEE802154_RX_TIMESTAMP) + /* AT86RF2XX_IS_PERIPH means the MCU is ATmegaRFR2 that has symbol counter */ + { + uint32_t rx_sc; + rx_sc = at86rf2xx_get_sc(dev); + + /* convert counter value to ns */ + uint64_t res = SC_TO_NS * (uint64_t)rx_sc; + netdev_ieee802154_rx_info_set_timestamp(radio_info, res); + DEBUG("[at86rf2xx] CS: %" PRIu32 " timestamp: %" PRIu32 ".%09" PRIu32 " ", + rx_sc, (uint32_t)(radio_info->timestamp / NS_PER_SEC), + (uint32_t)(radio_info->timestamp % NS_PER_SEC)); + } +#endif + } else { at86rf2xx_fb_stop(dev); diff --git a/drivers/at86rf2xx/include/at86rf2xx_internal.h b/drivers/at86rf2xx/include/at86rf2xx_internal.h index ce9da53fb8..79381cc25b 100644 --- a/drivers/at86rf2xx/include/at86rf2xx_internal.h +++ b/drivers/at86rf2xx/include/at86rf2xx_internal.h @@ -30,6 +30,8 @@ #if AT86RF2XX_IS_PERIPH #include +#include "irq.h" +#include "time_units.h" #endif #include "at86rf2xx_registers.h" @@ -293,6 +295,46 @@ static inline uint8_t at86rf2xx_get_irq_flags(at86rf2xx_t *dev) } +#if AT86RF2XX_IS_PERIPH +/* + * Read a 32 bit register as described in section 10.3 of the datasheet: A read + * of the least significant byte causes the current value to be atomically + * captured in a temporary 32 bit registers. The remaining reads will access this + * register instead. Only a single 32 bit temporary register is used to provide + * means to atomically access them. Thus, interrupts must be disabled during the + * read sequence in order to prevent other threads (or ISRs) from updating the + * temporary 32 bit register before the reading sequence has completed. + */ +static inline uint32_t reg32_read(volatile uint8_t *reg_ll) +{ + le_uint32_t reg; + unsigned state = irq_disable(); + reg.u8[0] = reg_ll[0]; + reg.u8[1] = reg_ll[1]; + reg.u8[2] = reg_ll[2]; + reg.u8[3] = reg_ll[3]; + irq_restore(state); + return reg.u32; +} + +/** + * @brief Get the timestamp of the packet in symbol counter ticks + * + * @param[in] dev pointer to the device descriptor + * + * @return the symbol counter value + */ +static inline uint32_t at86rf2xx_get_sc(const at86rf2xx_t *dev) +{ + (void) dev; + return reg32_read(&SCCNTLL); +} + +/* Symbol counter frequency is 62500Hz. One symbol counter tick is 16us = 16000 ns*/ +#define SC_TO_NS (16000LU) + +#endif + #ifdef __cplusplus } #endif diff --git a/sys/include/net/gnrc/netif/hdr.h b/sys/include/net/gnrc/netif/hdr.h index cb6489bf8f..bb13715ab6 100644 --- a/sys/include/net/gnrc/netif/hdr.h +++ b/sys/include/net/gnrc/netif/hdr.h @@ -29,6 +29,7 @@ #include "net/gnrc/pkt.h" #include "net/gnrc/pktbuf.h" #include "net/gnrc/netif.h" +#include "time_units.h" #ifdef __cplusplus extern "C" { diff --git a/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c b/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c index 64c72bff8b..1f254d3d4b 100644 --- a/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c +++ b/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c @@ -36,10 +36,14 @@ void gnrc_netif_hdr_print(gnrc_netif_hdr_t *hdr) if (hdr->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST) { printf("BROADCAST "); } - if (hdr->flags & GNRC_NETIF_HDR_FLAGS_MULTICAST) { printf("MULTICAST "); } +#if IS_USED(MODULE_GNRC_NETIF_TIMESTAMP) + if (hdr->flags & GNRC_NETIF_HDR_FLAGS_TIMESTAMP) { + printf("TIMESTAMP "); + } +#endif puts(""); } else { diff --git a/tests/net/gnrc_netif_ieee802154/Makefile b/tests/net/gnrc_netif_ieee802154/Makefile index 1e48d6a9a7..6e8e0f3226 100644 --- a/tests/net/gnrc_netif_ieee802154/Makefile +++ b/tests/net/gnrc_netif_ieee802154/Makefile @@ -1,19 +1,34 @@ -BOARD_WHITELIST = native +BOARD_WHITELIST = native derfmega256 avr-rss2 atmega256rfr2-xpro nrf52840dongle include ../Makefile.net_common -TERMFLAGS ?= -z "0.0.0.0:17755,localhost:17754" +ifeq (native, $(BOARD)) + USEMODULE += socket_zep + TERMFLAGS ?= -z "0.0.0.0:17755,localhost:17754" + USEMODULE += netdev + # somehow this breaks the test + DISABLE_MODULE += test_utils_print_stack_usage +else + USEMODULE += shell + USEMODULE += shell_cmds_default + USEMODULE += ps + # use the default network interface for the board + USEMODULE += netdev_default + # shell command to send L2 packets with a simple string + USEMODULE += gnrc_txtsnd + # module to test rx timestamp + USEMODULE += gnrc_netif_timestamp +endif -USEMODULE += socket_zep -USEMODULE += auto_init_gnrc_netif -USEMODULE += netdev +# gnrc is a meta module including all required, basic gnrc networking modules USEMODULE += gnrc +# automatically initialize the network interface +USEMODULE += auto_init_gnrc_netif +# use GNRC IEEE 802.15.4 as link-layer protocol USEMODULE += gnrc_netif_ieee802154 +# the application dumps received packets to stdout USEMODULE += gnrc_pktdump -# somehow this breaks the test -DISABLE_MODULE += test_utils_print_stack_usage - TEST_ON_CI_WHITELIST += native include $(RIOTBASE)/Makefile.include diff --git a/tests/net/gnrc_netif_ieee802154/main.c b/tests/net/gnrc_netif_ieee802154/main.c index 957d01fb5f..c9f216bbb0 100644 --- a/tests/net/gnrc_netif_ieee802154/main.c +++ b/tests/net/gnrc_netif_ieee802154/main.c @@ -17,20 +17,36 @@ #include "net/gnrc/netif.h" #include "net/gnrc/pktdump.h" +#if IS_USED(MODULE_SHELL) +#include +#include + +#include "thread.h" +#include "shell.h" +#endif + int main(void) { +#if IS_USED(MODULE_SOCKET_ZEP) + /* This is a test for native with socket_zep */ char addr_str[GNRC_NETIF_L2ADDR_MAXLEN * 3]; gnrc_netif_t *netif = gnrc_netif_iter(NULL); printf("l2_addr: %s\n", gnrc_netif_addr_to_str(netif->l2addr, netif->l2addr_len, addr_str)); - +#endif gnrc_netreg_entry_t dump = GNRC_NETREG_ENTRY_INIT_PID( GNRC_NETREG_DEMUX_CTX_ALL, gnrc_pktdump_pid ); gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &dump); + +#if IS_USED(MODULE_SHELL) + /* this is manual test for real MCU using shell module */ + char line_buf[SHELL_DEFAULT_BUFSIZE]; + shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE); +#endif return 0; }