From 795cd165fd0d553a42dc6abfd7c0e3cf6ba6f062 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 12 Dec 2019 15:58:44 +0100 Subject: [PATCH 1/8] ieee802154: add definitions for 802.15.4 PHY modes This adds PHY modes for IEEE 802.15.4-2003 and IEEE 802.15.4g-2012. --- sys/include/net/ieee802154.h | 16 +++++++++++++++- sys/include/net/netopt.h | 5 +++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/sys/include/net/ieee802154.h b/sys/include/net/ieee802154.h index 661eed1f68..0f0caa7eb9 100644 --- a/sys/include/net/ieee802154.h +++ b/sys/include/net/ieee802154.h @@ -94,7 +94,21 @@ extern "C" { #define IEEE802154_CHANNEL_MAX (26U) /**< Maximum channel for 2.4 GHz band */ /** @} */ -#define IEEE802154_FRAME_LEN_MAX (127U) /**< maximum frame length */ +#define IEEE802154_FRAME_LEN_MAX (127U) /**< maximum 802.15.4 frame length */ +#define IEEE802154G_FRAME_LEN_MAX (2047U) /**< maximum 802.15.4g-2012 frame length */ + +/** + * @brief 802.15.4 PHY modes + */ +enum { + IEEE802154_PHY_DISABLED, /**< PHY disabled, no mode selected */ + IEEE802154_PHY_BPSK, /**< Binary Phase Shift Keying */ + IEEE802154_PHY_ASK, /**< Amplitude-Shift Keying */ + IEEE802154_PHY_OQPSK, /**< Offset Quadrature Phase-Shift Keying */ + IEEE802154_PHY_MR_OQPSK, /**< Multi-Rate Offset Quadrature Phase-Shift Keying */ + IEEE802154_PHY_MR_OFDM, /**< Multi-Rate Orthogonal Frequency-Division Multiplexing */ + IEEE802154_PHY_MR_FSK /**< Multi-Rate Frequency Shift Keying */ +}; /** * @brief Special address definitions diff --git a/sys/include/net/netopt.h b/sys/include/net/netopt.h index b1739646c3..1c3bced331 100644 --- a/sys/include/net/netopt.h +++ b/sys/include/net/netopt.h @@ -651,6 +651,11 @@ typedef enum { */ NETOPT_LORAWAN_MIN_RX_SYMBOL, + /** + * @brief (uint8_t) 802.15.4 PHY mode + */ + NETOPT_IEEE802154_PHY, + /** * @brief (uint8_t*) phy layer syncword */ From fac35644d072477f187c77f69bafe9c889d9378b Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 13 Dec 2019 17:17:15 +0100 Subject: [PATCH 2/8] ieee802154: add definitions & config options for MR-O-QPSK Define options for IEEE 802.15.4g MR-O-QPSK as well as shell commands to set them via ifconfig. --- makefiles/pseudomodules.inc.mk | 1 + sys/include/net/ieee802154.h | 17 ++++ sys/include/net/netopt.h | 20 ++++ sys/net/crosslayer/netopt/netopt.c | 5 + sys/shell/commands/sc_gnrc_netif.c | 144 ++++++++++++++++++++++++++++- 5 files changed, 184 insertions(+), 3 deletions(-) diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index bd899cf7ed..17a7e18a1d 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -61,6 +61,7 @@ PSEUDOMODULES += mpu_stack_guard PSEUDOMODULES += mpu_noexec_ram PSEUDOMODULES += nanocoap_% PSEUDOMODULES += netdev_default +PSEUDOMODULES += netdev_ieee802154_% PSEUDOMODULES += netstats PSEUDOMODULES += netstats_l2 PSEUDOMODULES += netstats_ipv6 diff --git a/sys/include/net/ieee802154.h b/sys/include/net/ieee802154.h index 0f0caa7eb9..43b392a0a1 100644 --- a/sys/include/net/ieee802154.h +++ b/sys/include/net/ieee802154.h @@ -97,6 +97,14 @@ extern "C" { #define IEEE802154_FRAME_LEN_MAX (127U) /**< maximum 802.15.4 frame length */ #define IEEE802154G_FRAME_LEN_MAX (2047U) /**< maximum 802.15.4g-2012 frame length */ +/** + * For the SUN PHYs, the value is 1 ms expressed in symbol periods, rounded + * up to the next integer number of symbol periods using the ceiling() function. + * + * 802.15.4g, Table 70 (p. 43) + */ +#define IEEE802154G_ATURNAROUNDTIME_US (1 * US_PER_MS) + /** * @brief 802.15.4 PHY modes */ @@ -110,6 +118,15 @@ enum { IEEE802154_PHY_MR_FSK /**< Multi-Rate Frequency Shift Keying */ }; +/** + * @brief 802.15.4 forward error correction schemes + */ +enum { + IEEE802154_FEC_NONE, /**< no forward error correction */ + IEEE802154_FEC_NRNSC, /**< non-recursive and non-systematic code */ + IEEE802154_FEC_RSC /**< recursive and systematic code */ +}; + /** * @brief Special address definitions * @{ diff --git a/sys/include/net/netopt.h b/sys/include/net/netopt.h index 1c3bced331..54398370db 100644 --- a/sys/include/net/netopt.h +++ b/sys/include/net/netopt.h @@ -656,6 +656,26 @@ typedef enum { */ NETOPT_IEEE802154_PHY, + /** + * @brief (uint8_t) legacy O-QPSK Rate Mode + */ + NETOPT_OQPSK_RATE, + + /** + * @brief (uint8_t) MR-O-QPSK Chip Rate (kchip/s) + */ + NETOPT_MR_OQPSK_CHIPS, + + /** + * @brief (uint8_t) MR-O-QPSK Rate Mode + */ + NETOPT_MR_OQPSK_RATE, + + /** + * @brief (uint8_t) PHY Channel Spacing (kHz) + */ + NETOPT_CHANNEL_SPACING, + /** * @brief (uint8_t*) phy layer syncword */ diff --git a/sys/net/crosslayer/netopt/netopt.c b/sys/net/crosslayer/netopt/netopt.c index e9f420f1bb..683ab72732 100644 --- a/sys/net/crosslayer/netopt/netopt.c +++ b/sys/net/crosslayer/netopt/netopt.c @@ -106,6 +106,11 @@ static const char *_netopt_strmap[] = { [NETOPT_LORAWAN_RX2_FREQ] = "NETOPT_LORAWAN_RX2_FREQ", [NETOPT_LORAWAN_MAX_RX_ERROR] = "NETOPT_LORAWAN_MAX_RX_ERROR", [NETOPT_LORAWAN_MIN_RX_SYMBOL] = "NETOPT_LORAWAN_MIN_RX_SYMBOL", + [NETOPT_IEEE802154_PHY] = "NETOPT_IEEE802154_PHY", + [NETOPT_OQPSK_RATE] = "NETOPT_O-QPSK_RATE", + [NETOPT_MR_OQPSK_CHIPS] = "NETOPT_MR-O-QPSK_CHIPS", + [NETOPT_MR_OQPSK_RATE] = "NETOPT_MR-O-QPSK_RATE", + [NETOPT_CHANNEL_SPACING] = "NETOPT_CHANNEL_SPACING", [NETOPT_SYNCWORD] = "NETOPT_SYNCWORD", [NETOPT_RANDOM] = "NETOPT_RANDOM", [NETOPT_RX_SYMBOL_TIMEOUT] = "NETOPT_RX_SYMBOL_TIMEOUT", diff --git a/sys/shell/commands/sc_gnrc_netif.c b/sys/shell/commands/sc_gnrc_netif.c index f8e21722c6..c2f34d4caa 100644 --- a/sys/shell/commands/sc_gnrc_netif.c +++ b/sys/shell/commands/sc_gnrc_netif.c @@ -18,6 +18,7 @@ * @author Oliver Hahm */ +#include #include #include @@ -86,6 +87,15 @@ static void _print_iface_name(netif_t *iface) printf("%s", name); } +__attribute__ ((unused)) +static void str_toupper(char *str) +{ + while (*str) { + *str = toupper((unsigned) *str); + ++str; + } +} + #ifdef MODULE_NETSTATS static const char *_netstats_module_to_str(uint8_t module) { @@ -173,6 +183,13 @@ static void _set_usage(char *cmd_name) " * \"dr\" - sets datarate\n" " * \"rx2_dr\" - sets datarate of RX2 (lorawan)\n" " * \"nwkskey\" - sets Network Session Key\n" +#endif +#ifdef MODULE_NETDEV_IEEE802154_MULTIMODE + " * \"phy_mode\" - select PHY mode\n" +#endif +#ifdef MODULE_NETDEV_IEEE802154_MR_OQPSK + " * \"chip_rate\" - BPSK/QPSK chip rate in kChip/s\n" + " * \"rate_mode\" - BPSK/QPSK rate mode\n" #endif " * \"power\" - TX power in dBm\n" " * \"retrans\" - max. number of retransmissions\n" @@ -303,7 +320,33 @@ static void _print_netopt(netopt_t opt) case NETOPT_CODING_RATE: printf("coding rate"); break; -#endif +#endif /* MODULE_GNRC_NETIF_CMD_LORA */ +#ifdef MODULE_NETDEV_IEEE802154_MULTIMODE + + case NETOPT_IEEE802154_PHY: + printf("PHY mode"); + break; + +#endif /* MODULE_NETDEV_IEEE802154_MULTIMODE */ +#ifdef MODULE_NETDEV_IEEE802154_OQPSK + + case NETOPT_OQPSK_RATE: + printf("high rate"); + break; + +#endif /* MODULE_NETDEV_IEEE802154_OQPSK */ +#ifdef MODULE_NETDEV_IEEE802154_MR_OQPSK + + case NETOPT_MR_OQPSK_CHIPS: + printf("chip rate"); + break; + + case NETOPT_MR_OQPSK_RATE: + printf("rate mode"); + break; + +#endif /* MODULE_NETDEV_IEEE802154_MR_OQPSK */ + case NETOPT_CHECKSUM: printf("checksum"); break; @@ -359,6 +402,18 @@ static const char *_netopt_coding_rate_str[] = { }; #endif +#ifdef MODULE_NETDEV_IEEE802154 +static const char *_netopt_ieee802154_phy_str[] = { + [IEEE802154_PHY_DISABLED] = "DISABLED", + [IEEE802154_PHY_BPSK] = "BPSK", + [IEEE802154_PHY_ASK] = "ASK", + [IEEE802154_PHY_OQPSK] = "O-QPSK", + [IEEE802154_PHY_MR_OQPSK] = "MR-O-QPSK", + [IEEE802154_PHY_MR_OFDM] = "MR-OFDM", + [IEEE802154_PHY_MR_FSK] = "MR-FSK" +}; +#endif + /* for some lines threshold might just be 0, so we can't use _LINE_THRESHOLD * here */ static unsigned _newline(unsigned threshold, unsigned line_thresh) @@ -493,7 +548,42 @@ static void _netif_list(netif_t *iface) if (res >= 0) { printf(" CR: %s ", _netopt_coding_rate_str[u8]); } -#endif +#endif /* MODULE_GNRC_NETIF_CMD_LORA */ +#ifdef MODULE_NETDEV_IEEE802154 + res = netif_get_opt(iface, NETOPT_IEEE802154_PHY, 0, &u8, sizeof(u8)); + if (res >= 0) { + printf(" PHY: %s ", _netopt_ieee802154_phy_str[u8]); + switch (u8) { + +#ifdef MODULE_NETDEV_IEEE802154_OQPSK + case IEEE802154_PHY_OQPSK: + printf("\n "); + res = netif_get_opt(iface, NETOPT_OQPSK_RATE, 0, &u8, sizeof(u8)); + if (res >= 0 && u8) { + printf(" high data rate: %d ", u8); + } + + break; + +#endif /* MODULE_NETDEV_IEEE802154_OQPSK */ +#ifdef MODULE_NETDEV_IEEE802154_MR_OQPSK + case IEEE802154_PHY_MR_OQPSK: + printf("\n "); + res = netif_get_opt(iface, NETOPT_MR_OQPSK_CHIPS, 0, &u16, sizeof(u16)); + if (res >= 0) { + printf(" chip rate: %u ", u16); + } + res = netif_get_opt(iface, NETOPT_MR_OQPSK_RATE, 0, &u8, sizeof(u8)); + if (res >= 0) { + printf(" rate mode: %d ", u8); + } + + break; + +#endif /* MODULE_NETDEV_IEEE802154_MR_OQPSK */ + } + } +#endif /* MODULE_NETDEV_IEEE802154 */ netopt_enable_t link; res = netif_get_opt(iface, NETOPT_LINK, 0, &link, sizeof(netopt_enable_t)); if (res >= 0) { @@ -781,6 +871,36 @@ static int _netif_set_coding_rate(netif_t *iface, char *value) } #endif /* MODULE_GNRC_NETIF_CMD_LORA */ +#ifdef MODULE_NETDEV_IEEE802154_MULTIMODE +static int _netif_set_ieee802154_phy_mode(netif_t *iface, char *value) +{ + /* ignore case */ + str_toupper(value); + + for (uint8_t i = 0; i < ARRAY_SIZE(_netopt_ieee802154_phy_str); ++i) { + + if (strcmp(_netopt_ieee802154_phy_str[i], value)) { + continue; + } + + if (netif_set_opt(iface, NETOPT_IEEE802154_PHY, 0, &i, sizeof(uint8_t)) < 0) { + printf("error: unable to set PHY mode to %s\n", value); + return 1; + } + + printf("success: set PHY mode %s\n", value); + return 0; + } + + printf("usage: ifconfig set phy "); + for (unsigned i = 0; i < ARRAY_SIZE(_netopt_ieee802154_phy_str); ++i) { + printf("%c%s", i ? '|' : '[', _netopt_ieee802154_phy_str[i]); + } + puts("]"); + return 1; +} +#endif /* MODULE_NETDEV_IEEE802154_MULTIMODE */ + static int _netif_set_u16(netif_t *iface, netopt_t opt, uint16_t context, char *u16_str) { @@ -1162,7 +1282,25 @@ static int _netif_set(char *cmd_name, netif_t *iface, char *key, char *value) else if (strcmp("rx2_dr", key) == 0) { return _netif_set_u8(iface, NETOPT_LORAWAN_RX2_DR, 0, value); } -#endif +#endif /* MODULE_GNRC_NETIF_CMD_LORA */ +#ifdef MODULE_NETDEV_IEEE802154_MULTIMODE + else if ((strcmp("phy_mode", key) == 0) || (strcmp("phy", key) == 0)) { + return _netif_set_ieee802154_phy_mode(iface, value); + } +#endif /* MODULE_NETDEV_IEEE802154_MULTIMODE */ +#ifdef MODULE_NETDEV_IEEE802154_OQPSK + else if (strcmp("high_rate", key) == 0) { + return _netif_set_u8(iface, NETOPT_OQPSK_RATE, 0, value); + } +#endif /* MODULE_NETDEV_IEEE802154_OQPSK */ +#ifdef MODULE_NETDEV_IEEE802154_MR_OQPSK + else if ((strcmp("chip_rate", key) == 0) || (strcmp("chips", key) == 0)) { + return _netif_set_u16(iface, NETOPT_MR_OQPSK_CHIPS, 0, value); + } + else if (strcmp("rate_mode", key) == 0) { + return _netif_set_u8(iface, NETOPT_MR_OQPSK_RATE, 0, value); + } +#endif /* MODULE_NETDEV_IEEE802154_MR_OQPSK */ else if ((strcmp("channel", key) == 0) || (strcmp("chan", key) == 0)) { return _netif_set_u16(iface, NETOPT_CHANNEL, 0, value); } From c77119957fcd6b67e8cbaf8f10c02bced6748547 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 13 Dec 2019 17:18:13 +0100 Subject: [PATCH 3/8] shell/sc_gnrc_netif: fix space after NID All option have a space behind them. This fixes the formatting of the NID parameter if there are options after it. --- sys/shell/commands/sc_gnrc_netif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/shell/commands/sc_gnrc_netif.c b/sys/shell/commands/sc_gnrc_netif.c index c2f34d4caa..3010e6f7c1 100644 --- a/sys/shell/commands/sc_gnrc_netif.c +++ b/sys/shell/commands/sc_gnrc_netif.c @@ -533,7 +533,7 @@ static void _netif_list(netif_t *iface) } res = netif_get_opt(iface, NETOPT_NID, 0, &u16, sizeof(u16)); if (res >= 0) { - printf(" NID: 0x%" PRIx16, u16); + printf(" NID: 0x%" PRIx16 " ", u16); } #ifdef MODULE_GNRC_NETIF_CMD_LORA res = netif_get_opt(iface, NETOPT_BANDWIDTH, 0, &u8, sizeof(u8)); From cfc2feca1de5a07a59773e2cdd2872510766a010 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 12 Dec 2019 16:02:09 +0100 Subject: [PATCH 4/8] ieee802154: return PDU based on PHY mode IEEE 802.15.4g-2012 specifies a PDU of 2047 for it's PHY modes, so query the driver for the mode before returning the PDU. If none of the new modes is used, don't query the driver to not incure a penalty on existing platforms. --- drivers/netdev_ieee802154/netdev_ieee802154.c | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/netdev_ieee802154/netdev_ieee802154.c b/drivers/netdev_ieee802154/netdev_ieee802154.c index 4a168d876c..3a973a1a6c 100644 --- a/drivers/netdev_ieee802154/netdev_ieee802154.c +++ b/drivers/netdev_ieee802154/netdev_ieee802154.c @@ -71,6 +71,36 @@ void netdev_ieee802154_reset(netdev_ieee802154_t *dev) dev->netdev.driver->set(&dev->netdev, NETOPT_NID, &dev->pan, sizeof(dev->pan)); } +static inline uint16_t _get_ieee802154_pdu(netdev_ieee802154_t *dev) +{ +#if defined(MODULE_NETDEV_IEEE802154_MR_OQPSK) || \ + defined(MODULE_NETDEV_IEEE802154_MR_OFDM) || \ + defined(MODULE_NETDEV_IEEE802154_MR_FSK) + uint8_t type = IEEE802154_PHY_DISABLED; + dev->netdev.driver->get(&dev->netdev, NETOPT_IEEE802154_PHY, &type, sizeof(type)); +#else + (void) dev; +#endif + +#ifdef MODULE_NETDEV_IEEE802154_MR_OQPSK + if (type == IEEE802154_PHY_MR_OQPSK) { + return IEEE802154G_FRAME_LEN_MAX; + } +#endif +#ifdef MODULE_NETDEV_IEEE802154_MR_OFDM + if (type == IEEE802154_PHY_MR_OFDM) { + return IEEE802154G_FRAME_LEN_MAX; + } +#endif +#ifdef MODULE_NETDEV_IEEE802154_MR_FSK + if (type == IEEE802154_PHY_MR_FSK) { + return IEEE802154G_FRAME_LEN_MAX; + } +#endif + + return IEEE802154_FRAME_LEN_MAX; +} + int netdev_ieee802154_get(netdev_ieee802154_t *dev, netopt_t opt, void *value, size_t max_len) { @@ -152,9 +182,10 @@ int netdev_ieee802154_get(netdev_ieee802154_t *dev, netopt_t opt, void *value, #endif case NETOPT_MAX_PDU_SIZE: assert(max_len >= sizeof(int16_t)); - *((uint16_t *)value) = (IEEE802154_FRAME_LEN_MAX - - IEEE802154_MAX_HDR_LEN) - - IEEE802154_FCS_LEN; + + *((uint16_t *)value) = (_get_ieee802154_pdu(dev) + - IEEE802154_MAX_HDR_LEN) + - IEEE802154_FCS_LEN; res = sizeof(uint16_t); break; default: From 0cf9f6aa7ff8c7178394309ea906c6d8aae52ae5 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 23 Mar 2020 22:39:35 +0100 Subject: [PATCH 5/8] drivers/at86rf215: implement at86rf215_get_phy_mode() --- drivers/Makefile.dep | 4 ++++ drivers/at86rf215/at86rf215_getset.c | 12 ++++++++++++ drivers/at86rf215/at86rf215_netdev.c | 16 ++++++++++++++++ drivers/at86rf215/include/at86rf215_internal.h | 12 ++++++++++++ drivers/include/at86rf215.h | 7 +++++++ 5 files changed, 51 insertions(+) diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index ee01562838..33bbed9def 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -70,6 +70,10 @@ ifneq (,$(filter at86rf215%,$(USEMODULE))) DEFAULT_MODULE += auto_init_at86rf215 DEFAULT_MODULE += at86rf215_subghz + DEFAULT_MODULE += netdev_ieee802154_multimode + + DEFAULT_MODULE += netdev_ieee802154_oqpsk + ifeq (,$(filter at86rf215m,$(USEMODULE))) DEFAULT_MODULE += at86rf215_24ghz endif diff --git a/drivers/at86rf215/at86rf215_getset.c b/drivers/at86rf215/at86rf215_getset.c index 9016340916..940149267b 100644 --- a/drivers/at86rf215/at86rf215_getset.c +++ b/drivers/at86rf215/at86rf215_getset.c @@ -114,6 +114,18 @@ uint16_t at86rf215_get_channel_spacing(at86rf215_t *dev) { return 25 * at86rf215_reg_read(dev, dev->RF->RG_CS); } +uint8_t at86rf215_get_phy_mode(at86rf215_t *dev) +{ + switch (at86rf215_reg_read(dev, dev->BBC->RG_PC) & PC_PT_MASK) { + case 0x1: return IEEE802154_PHY_MR_FSK; + case 0x2: return IEEE802154_PHY_MR_OFDM; + case 0x3: return at86rf215_OQPSK_is_legacy(dev) + ? IEEE802154_PHY_OQPSK + : IEEE802154_PHY_MR_OQPSK; + default: return IEEE802154_PHY_DISABLED; + } +} + uint16_t at86rf215_get_pan(const at86rf215_t *dev, uint8_t filter) { if (filter > 3) { diff --git a/drivers/at86rf215/at86rf215_netdev.c b/drivers/at86rf215/at86rf215_netdev.c index c42b5a7816..21f5308a38 100644 --- a/drivers/at86rf215/at86rf215_netdev.c +++ b/drivers/at86rf215/at86rf215_netdev.c @@ -384,6 +384,12 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) res = max_len; break; + case NETOPT_IEEE802154_PHY: + assert(max_len >= sizeof(int8_t)); + *((int8_t *)val) = at86rf215_get_phy_mode(dev); + res = max_len; + break; + default: res = -ENOTSUP; break; @@ -528,6 +534,16 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) res = sizeof(int8_t); break; + case NETOPT_IEEE802154_PHY: + assert(len <= sizeof(uint8_t)); + switch (*(uint8_t *)val) { + case IEEE802154_PHY_OQPSK: + at86rf215_configure_legacy_OQPSK(dev, at86rf215_OQPSK_get_mode_legacy(dev)); + res = sizeof(uint8_t); + break; + default: + return -ENOTSUP; + } default: break; } diff --git a/drivers/at86rf215/include/at86rf215_internal.h b/drivers/at86rf215/include/at86rf215_internal.h index 80f1817e69..091cdb5e6a 100644 --- a/drivers/at86rf215/include/at86rf215_internal.h +++ b/drivers/at86rf215/include/at86rf215_internal.h @@ -158,6 +158,18 @@ void at86rf215_get_random(at86rf215_t *dev, void *data, size_t len); */ int at86rf215_configure_legacy_OQPSK(at86rf215_t *dev, bool high_rate); +/** + * @brief Get the current PHY modulation. + * May be @ref IEEE802154_PHY_MR_FSK, @ref IEEE802154_PHY_MR_OFDM, + * @ref IEEE802154_PHY_MR_OQPSK, @ref IEEE802154_PHY_OQPSK + * or @ref IEEE802154_PHY_DISABLED. + * + * @param[in] dev device to read from + * + * @return the current PHY mode the device is operating with + */ +uint8_t at86rf215_get_phy_mode(at86rf215_t *dev); + /** * @brief Check if a channel number is valid. * The function takes the current frequency band and modulation into diff --git a/drivers/include/at86rf215.h b/drivers/include/at86rf215.h index 22bcf24a94..b54d2178c3 100644 --- a/drivers/include/at86rf215.h +++ b/drivers/include/at86rf215.h @@ -119,6 +119,13 @@ typedef enum { } at86rf215_state_t; /** @} */ +enum { + AT86RF215_MODE_LEGACY_OQPSK, + AT86RF215_MODE_MR_OQPSK, + AT86RF215_MODE_MR_OFDM, + AT86RF215_MODE_MR_FSK +}; + /** * @name Internal device option flags * @{ From e6d47aa825e8e612c2baeb77ea654511bb2f5a7e Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 23 Mar 2020 22:44:03 +0100 Subject: [PATCH 6/8] drivers/at86rf215: implement MR-O-QPSK --- drivers/Makefile.dep | 1 + drivers/at86rf215/at86rf215.c | 10 +- drivers/at86rf215/at86rf215_netdev.c | 88 +++++++ drivers/at86rf215/at86rf215_o-qpsk.c | 225 ++++++++++++++++-- .../at86rf215/include/at86rf215_internal.h | 95 +++++++- drivers/include/at86rf215.h | 37 +++ 6 files changed, 430 insertions(+), 26 deletions(-) diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 33bbed9def..532ad0fe3f 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -73,6 +73,7 @@ ifneq (,$(filter at86rf215%,$(USEMODULE))) DEFAULT_MODULE += netdev_ieee802154_multimode DEFAULT_MODULE += netdev_ieee802154_oqpsk + DEFAULT_MODULE += netdev_ieee802154_mr_oqpsk ifeq (,$(filter at86rf215m,$(USEMODULE))) DEFAULT_MODULE += at86rf215_24ghz diff --git a/drivers/at86rf215/at86rf215.c b/drivers/at86rf215/at86rf215.c index f48e2b6000..0dfc1e4af2 100644 --- a/drivers/at86rf215/at86rf215.c +++ b/drivers/at86rf215/at86rf215.c @@ -17,7 +17,6 @@ * @} */ - #include "luid.h" #include "byteorder.h" #include "net/ieee802154.h" @@ -145,8 +144,13 @@ void at86rf215_reset(at86rf215_t *dev) at86rf215_reg_write(dev, dev->BBC->RG_AMCS, reg); - /* set compatibility with first-gen 802.15.4 devices */ - at86rf215_configure_legacy_OQPSK(dev, 0); + if (AT86RF215_DEFAULT_PHY_MODE == IEEE802154_PHY_OQPSK) { + at86rf215_configure_legacy_OQPSK(dev, 0); + } + if (AT86RF215_DEFAULT_PHY_MODE == IEEE802154_PHY_MR_OQPSK) { + at86rf215_configure_OQPSK(dev, AT86RF215_DEFAULT_MR_OQPSK_CHIPS, + AT86RF215_DEFAULT_MR_OQPSK_RATE); + } /* set default channel */ at86rf215_set_chan(dev, dev->netdev.chan); diff --git a/drivers/at86rf215/at86rf215_netdev.c b/drivers/at86rf215/at86rf215_netdev.c index 21f5308a38..8d34160608 100644 --- a/drivers/at86rf215/at86rf215_netdev.c +++ b/drivers/at86rf215/at86rf215_netdev.c @@ -327,6 +327,10 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) case NETOPT_CHANNEL_PAGE: assert(max_len >= sizeof(uint16_t)); + if (at86rf215_get_phy_mode(dev) != IEEE802154_PHY_OQPSK) { + return -ENOTSUP; + } + ((uint8_t *)val)[1] = 0; ((uint8_t *)val)[0] = is_subGHz(dev) ? 2 : 0; return sizeof(uint16_t); @@ -390,6 +394,29 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) res = max_len; break; + case NETOPT_MR_OQPSK_CHIPS: + assert(max_len >= sizeof(int16_t)); + switch (at86rf215_OQPSK_get_chips(dev)) { + case 0: *((int16_t *)val) = 100; break; + case 1: *((int16_t *)val) = 200; break; + case 2: *((int16_t *)val) = 1000; break; + case 3: *((int16_t *)val) = 2000; break; + } + res = max_len; + break; + + case NETOPT_MR_OQPSK_RATE: + assert(max_len >= sizeof(int8_t)); + *((int8_t *)val) = at86rf215_OQPSK_get_mode(dev); + res = max_len; + break; + + case NETOPT_OQPSK_RATE: + assert(max_len >= sizeof(int8_t)); + *((int8_t *)val) = at86rf215_OQPSK_get_mode_legacy(dev); + res = max_len; + break; + default: res = -ENOTSUP; break; @@ -541,9 +568,70 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) at86rf215_configure_legacy_OQPSK(dev, at86rf215_OQPSK_get_mode_legacy(dev)); res = sizeof(uint8_t); break; + case IEEE802154_PHY_MR_OQPSK: + at86rf215_configure_OQPSK(dev, + at86rf215_OQPSK_get_chips(dev), + at86rf215_OQPSK_get_mode(dev)); + res = sizeof(uint8_t); + break; default: return -ENOTSUP; } + break; + + case NETOPT_MR_OQPSK_CHIPS: + if (at86rf215_get_phy_mode(dev) != IEEE802154_PHY_MR_OQPSK) { + return -ENOTSUP; + } + + uint8_t chips; + assert(len <= sizeof(uint16_t)); + if (*((const uint16_t *)val) == 100) { + chips = 0; + } else if (*((const uint16_t *)val) == 200) { + chips = 1; + } else if (*((const uint16_t *)val) == 1000) { + chips = 2; + } else if (*((const uint16_t *)val) == 2000) { + chips = 3; + } else { + res = -EINVAL; + break; + } + + if (at86rf215_OQPSK_set_chips(dev, chips) == 0) { + res = sizeof(uint8_t); + } else { + res = -ERANGE; + } + break; + + case NETOPT_MR_OQPSK_RATE: + if (at86rf215_get_phy_mode(dev) != IEEE802154_PHY_MR_OQPSK) { + return -ENOTSUP; + } + + assert(len <= sizeof(uint8_t)); + if (at86rf215_OQPSK_set_mode(dev, *(uint8_t *)val) == 0) { + res = sizeof(uint8_t); + } else { + res = -ERANGE; + } + break; + + case NETOPT_OQPSK_RATE: + if (at86rf215_get_phy_mode(dev) != IEEE802154_PHY_OQPSK) { + return -ENOTSUP; + } + + assert(len <= sizeof(uint8_t)); + if (at86rf215_OQPSK_set_mode_legacy(dev, *(uint8_t *)val) == 0) { + res = sizeof(uint8_t); + } else { + res = -ERANGE; + } + break; + default: break; } diff --git a/drivers/at86rf215/at86rf215_o-qpsk.c b/drivers/at86rf215/at86rf215_o-qpsk.c index c978eaabf3..782a558706 100644 --- a/drivers/at86rf215/at86rf215_o-qpsk.c +++ b/drivers/at86rf215/at86rf215_o-qpsk.c @@ -34,6 +34,8 @@ #define QPSK_CHANNEL_SPACING_24GHZ (5000U) /* kHz */ #define QPSK_CENTER_FREQUENCY_24GHZ (2350000U - CCF0_24G_OFFSET) /* Hz */ +#define LEGACY_QPSK_SYMBOL_TIME_US (16) + /* Table 6-103. O-QPSK Transmitter Frontend Configuration */ static uint8_t _TXCUTC_PARAMP(uint8_t chips) { @@ -148,20 +150,88 @@ static inline uint8_t _AGCC(uint8_t chips) } } -/* Table 6-100. MR-O-QPSK Modes */ -static uint32_t _get_bitrate(uint8_t chips, uint8_t mode) +static inline uint16_t _get_symbol_duration_us(uint8_t chips) { + /* 802.15.4g, Table 183 / Table 165 */ switch (chips) { case BB_FCHIP100: - return 6250 * (1 << mode); + return 320; case BB_FCHIP200: - return 12500 * (1 << mode); + return 160; case BB_FCHIP1000: case BB_FCHIP2000: - return mode ? 125000 * (1 << (mode - 1)) : 31250; + default: + return 64; + } +} + +static inline uint8_t _get_cca_duration_syms(uint8_t chips) +{ + /* 802.15.4g, Table 188 */ + return (chips < BB_FCHIP1000) ? 4 : 8; +} + +static inline uint8_t _get_shr_duration_syms(uint8_t chips) +{ + /* 802.15.4g, Table 184 / Table 165 */ + return (chips < BB_FCHIP1000) ? 48 : 72; +} + +static uint8_t _get_spreading(uint8_t chips, uint8_t mode) +{ + if (mode == 4) { + return 1; } - return 0; + uint8_t spread = 1 << (3 - mode); + + if (chips == BB_FCHIP1000) { + return 2 * spread; + } + + if (chips == BB_FCHIP2000) { + return 4 * spread; + } + + return spread; +} + +static inline uint8_t _get_ack_psdu_duration_syms(uint8_t chips, uint8_t mode) +{ + /* pg. 119, section 18.3.2.14 */ + static const uint8_t sym_len[] = { 32, 32, 64, 128 }; + const uint8_t Ns = sym_len[chips]; + const uint8_t Rspread = _get_spreading(chips, mode); + /* Nd == 63, since ACK length is 5 or 7 octects only */ + const uint16_t Npsdu = Rspread * 2 * 63; + + /* phyPSDUDuration = ceiling(Npsdu / Ns) + ceiling(Npsdu / Mp) */ + /* with Mp = Np * 16, see Table 182 */ + return (Npsdu + Ns/2) / Ns + (Npsdu + 8 * Ns) / (16 * Ns); +} + +static uint8_t _set_mode(at86rf215_t *dev, uint8_t mode) +{ + mode = AT86RF215_MR_OQPSK_MODE(mode); + + /* TX with selected rate mode */ + at86rf215_reg_write(dev, dev->BBC->RG_OQPSKPHRTX, mode); + + /* power save mode only works when not listening to legacy frames */ + /* listening to both uses ~1mA more that just listening to legacy */ + /* TODO: make this configurable */ + uint8_t rxm = RXM_MR_OQPSK; + + if (dev->flags & AT86RF215_OPT_RPC) { + rxm |= OQPSKC2_RPC_MASK; /* enable Reduced Power Consumption */ + } + + at86rf215_reg_write(dev, dev->BBC->RG_OQPSKC2, + rxm /* receive mode, MR-O-QPSK */ + | OQPSKC2_FCSTLEG_MASK /* 16 bit frame checksum */ + | OQPSKC2_ENPROP_MASK); /* enable RX of proprietary modes */ + + return mode; } static void _set_chips(at86rf215_t *dev, uint8_t chips) @@ -222,18 +292,38 @@ static void _set_legacy(at86rf215_t *dev, bool high_rate) | OQPSKC2_ENPROP_MASK); /* enable RX of proprietary modes */ } +static inline void _set_ack_timeout_legacy(at86rf215_t *dev) +{ + dev->ack_timeout_usec = AT86RF215_ACK_PERIOD_IN_SYMBOLS * LEGACY_QPSK_SYMBOL_TIME_US; + DEBUG("[%s] ACK timeout: %"PRIu32" µs\n", "legacy O-QPSK", dev->ack_timeout_usec); +} + static void _set_ack_timeout(at86rf215_t *dev, uint8_t chips, uint8_t mode) { - dev->ack_timeout_usec = AT86RF215_ACK_PERIOD_IN_BITS * US_PER_SEC / _get_bitrate(chips, mode); + /* see 802.15.4g-2012, p. 30 */ + uint16_t symbols = _get_cca_duration_syms(chips) + + _get_shr_duration_syms(chips) + + 15 /* PHR duration */ + + _get_ack_psdu_duration_syms(chips, mode); + + dev->ack_timeout_usec = _get_symbol_duration_us(chips) * symbols + + IEEE802154G_ATURNAROUNDTIME_US; + DEBUG("[%s] ACK timeout: %"PRIu32" µs\n", "O-QPSK", dev->ack_timeout_usec); } -static void _set_csma_backoff_period(at86rf215_t *dev, uint8_t chips, uint8_t mode) +static inline void _set_csma_backoff_period(at86rf215_t *dev, uint8_t chips) { - dev->csma_backoff_period = AT86RF215_BACKOFF_PERIOD_IN_BITS * US_PER_SEC / _get_bitrate(chips, mode); + dev->csma_backoff_period = AT86RF215_BACKOFF_PERIOD_IN_SYMBOLS * _get_symbol_duration_us(chips); DEBUG("[%s] CSMA BACKOFF: %"PRIu32" µs\n", "O-QPSK", dev->csma_backoff_period); } +static inline void _set_csma_backoff_period_legacy(at86rf215_t *dev) +{ + dev->csma_backoff_period = AT86RF215_BACKOFF_PERIOD_IN_SYMBOLS * LEGACY_QPSK_SYMBOL_TIME_US; + DEBUG("[%s] CSMA BACKOFF: %"PRIu32" µs\n", "legacy O-QPSK", dev->csma_backoff_period); +} + void _end_configure_OQPSK(at86rf215_t *dev) { /* set channel spacing with 25 kHz resolution */ @@ -256,22 +346,127 @@ void _end_configure_OQPSK(at86rf215_t *dev) at86rf215_enable_radio(dev, BB_MROQPSK); } -int at86rf215_configure_legacy_OQPSK(at86rf215_t *dev, bool high_rate) +int at86rf215_configure_OQPSK(at86rf215_t *dev, uint8_t chips, uint8_t mode) { - /* select 'mode' that would result in the approprate MR-O-QPSK data rate */ - uint8_t mode = high_rate ? 3 : 2; - uint8_t chips = is_subGHz(dev) ? BB_FCHIP1000 : BB_FCHIP2000; + if (chips > BB_FCHIP2000) { + DEBUG("[%s] invalid chips: %d\n", __func__, chips); + return -EINVAL; + } + + if (mode > 4) { + DEBUG("[%s] invalid mode: %d\n", __func__, mode); + return -EINVAL; + } + + /* mode 4 only supports 2000 kchip/s */ + if (mode == 4 && chips != BB_FCHIP2000) { + DEBUG("[%s] mode 4 only supports 2000 kChip/s\n", __func__); + return -EINVAL; + } at86rf215_await_state_end(dev, RF_STATE_TX); /* disable radio */ at86rf215_reg_write(dev, dev->BBC->RG_PC, 0); - _set_legacy(dev, high_rate); - _set_csma_backoff_period(dev, chips, mode); + _set_mode(dev, mode); + _set_chips(dev, chips); + _set_csma_backoff_period(dev, chips); _set_ack_timeout(dev, chips, mode); _end_configure_OQPSK(dev); return 0; } + +int at86rf215_configure_legacy_OQPSK(at86rf215_t *dev, bool high_rate) +{ + at86rf215_await_state_end(dev, RF_STATE_TX); + + /* disable radio */ + at86rf215_reg_write(dev, dev->BBC->RG_PC, 0); + + _set_legacy(dev, high_rate); + _set_csma_backoff_period_legacy(dev); + _set_ack_timeout_legacy(dev); + + _end_configure_OQPSK(dev); + + return 0; +} + +int at86rf215_OQPSK_set_chips(at86rf215_t *dev, uint8_t chips) +{ + uint8_t mode; + + mode = at86rf215_reg_read(dev, dev->BBC->RG_OQPSKPHRTX); + + if (mode & AT86RF215_OQPSK_MODE_LEGACY) { + DEBUG("[%s] can't set chip rate in legacy mode\n", __func__); + return -1; + } + + at86rf215_await_state_end(dev, RF_STATE_TX); + + _set_chips(dev, chips); + _set_csma_backoff_period(dev, chips); + _set_ack_timeout(dev, chips, mode >> OQPSKPHRTX_MOD_SHIFT); + + return 0; +} + +uint8_t at86rf215_OQPSK_get_chips(at86rf215_t *dev) +{ + return at86rf215_reg_read(dev, dev->BBC->RG_OQPSKC0) & OQPSKC0_FCHIP_MASK; +} + +int at86rf215_OQPSK_set_mode(at86rf215_t *dev, uint8_t mode) +{ + if (mode > 4) { + return -1; + } + + uint8_t chips = at86rf215_OQPSK_get_chips(dev); + + at86rf215_await_state_end(dev, RF_STATE_TX); + + if (mode == 4 && chips != BB_FCHIP2000) { + _set_chips(dev, BB_FCHIP2000); + } + + _set_mode(dev, mode); + _set_csma_backoff_period(dev, chips); + _set_ack_timeout(dev, chips, mode); + + return 0; +} + +uint8_t at86rf215_OQPSK_get_mode(at86rf215_t *dev) +{ + uint8_t mode = at86rf215_reg_read(dev, dev->BBC->RG_OQPSKPHRTX); + return (mode & OQPSKPHRTX_MOD_MASK) >> OQPSKPHRTX_MOD_SHIFT; +} + +int at86rf215_OQPSK_set_mode_legacy(at86rf215_t *dev, bool high_rate) +{ + /* enable/disable legacy high data rate */ + if (high_rate) { + at86rf215_reg_write(dev, dev->BBC->RG_OQPSKC3, OQPSKC3_HRLEG_MASK); + } else { + at86rf215_reg_write(dev, dev->BBC->RG_OQPSKC3, 0); + } + + _set_csma_backoff_period_legacy(dev); + _set_ack_timeout_legacy(dev); + + return 0; +} + +uint8_t at86rf215_OQPSK_get_mode_legacy(at86rf215_t *dev) +{ + if (at86rf215_reg_read(dev, dev->BBC->RG_OQPSKC3) & OQPSKC3_HRLEG_MASK) { + return 1; + } + + return 0; +} diff --git a/drivers/at86rf215/include/at86rf215_internal.h b/drivers/at86rf215/include/at86rf215_internal.h index 091cdb5e6a..514f63f439 100644 --- a/drivers/at86rf215/include/at86rf215_internal.h +++ b/drivers/at86rf215/include/at86rf215_internal.h @@ -46,8 +46,6 @@ extern "C" { */ /** 20 symbols is the std period length */ #define AT86RF215_BACKOFF_PERIOD_IN_SYMBOLS (20U) -/** in 802.15.4 oqpsk each symble is 4 bits, not about the others */ -#define AT86RF215_BACKOFF_PERIOD_IN_BITS (AT86RF215_BACKOFF_PERIOD_IN_SYMBOLS * 4) /** * Default Parameters for 802.15.4 retransmissions & CSMA @@ -59,10 +57,6 @@ extern "C" { #define AT86RF215_CSMA_MAX_BE_DEFAULT (5) /** @} */ -/** For the SUN PHYs, the value is 1 ms expressed in symbol periods, rounded up to the next - integer number of symbol periods using the ceiling() function */ -#define AT86RF215_TURNAROUND_TIME_US (1 * US_PER_MS) - /** An ACK consists of 5 payload bytes */ #define AT86RF215_ACK_PSDU_BYTES (5) @@ -71,8 +65,6 @@ extern "C" { * AT86RF233 uses an ACK timeout of 54 symbol periods, or 864 µs @ 250 kbit/s * -> 864µs * 250kbit/s = 216 bit */ #define AT86RF215_ACK_PERIOD_IN_SYMBOLS (54U) -/** in 802.15.4 oqpsk each symble is 4 bits, not about the others */ -#define AT86RF215_ACK_PERIOD_IN_BITS (AT86RF215_ACK_PERIOD_IN_SYMBOLS * 4) #define AT86RF215_OQPSK_MODE_LEGACY (0x1) /**< legacy mode, 250 kbit/s */ #define AT86RF215_OQPSK_MODE_LEGACY_HDR (0x3) /**< legacy mode, high data rate */ @@ -158,6 +150,93 @@ void at86rf215_get_random(at86rf215_t *dev, void *data, size_t len); */ int at86rf215_configure_legacy_OQPSK(at86rf215_t *dev, bool high_rate); +/** + * @brief Configure the radio to make use of O-QPSK modulation. + * The chip rate is the number of bits per second (chips per second) used in the spreading signal. + * The rate mode may be + * - @ref AT86RF215_OQPSK_MODE_LEGACY for compatibility with first-gen 802.15.4 devices (250 kbit/s) + * - @ref AT86RF215_OQPSK_MODE_LEGACY_HDR for compatibility with the proprietary high-data rate mode + * of the at86rf233 (1000 kbit/s, 2.4 GHz) and at86rf212b (500 kbit/s, sub-GHz) + * - @ref AT86RF215_MR_OQPSK_MODE for the rate modes specified in 802.15.4g-2012 + * + * @param[in] dev device to configure + * @param[in] chips chip rate, `BB_FCHIP100` … `BB_FCHIP2000` + * @param[in] rate rate mode, may be @ref AT86RF215_OQPSK_MODE_LEGACY or @ref AT86RF215_MR_OQPSK_MODE + * + * @return 0 on success, error otherwise + */ +int at86rf215_configure_OQPSK(at86rf215_t *dev, uint8_t chips, uint8_t rate); + +/** + * @brief Get the current O-QPSK chip rate + * + * @param[in] dev device to read from + * + * @return the current chip rate + */ +uint8_t at86rf215_OQPSK_get_chips(at86rf215_t *dev); + +/** + * @brief Set the current O-QPSK chip rate + * + * @param[in] dev device to configure + * @param[in] chips chip rate in chip/s + * + * @return 0 on success, error otherwise + */ +int at86rf215_OQPSK_set_chips(at86rf215_t *dev, uint8_t chips); + +/** + * @brief Get the current O-QPSK rate mode + * + * @param[in] dev device to read from + * + * @return the current rate mode + */ +uint8_t at86rf215_OQPSK_get_mode(at86rf215_t *dev); + +/** + * @brief Set the current O-QPSK rate mode + * + * @param[in] dev device to configure + * @param[in] mode rate mode + * + * @return 0 on success, error otherwise + */ +int at86rf215_OQPSK_set_mode(at86rf215_t *dev, uint8_t mode); + +/** + * @brief Get the current legacy O-QPSK mode + * + * @param[in] dev device to read from + * + * @return 0 for IEEE 802.15.4 mode, 1 for high data rate + */ +uint8_t at86rf215_OQPSK_get_mode_legacy(at86rf215_t *dev); + +/** + * @brief Set the current legacy O-QPSK rate mode + * + * @param[in] dev device to configure + * @param[in] high_rate set to use proprietary high data rate + * + * @return 0 on success, error otherwise + */ +int at86rf215_OQPSK_set_mode_legacy(at86rf215_t *dev, bool high_rate); + +/** + * @brief Test if O-QPSK PHY operates in legacy mode + * + * @param[in] dev device to test + * + * @return true if device operates in legacy mode + */ +static inline bool at86rf215_OQPSK_is_legacy(at86rf215_t *dev) { + return at86rf215_reg_read(dev, dev->BBC->RG_OQPSKPHRTX) & AT86RF215_OQPSK_MODE_LEGACY; +} + +/** @} */ + /** * @brief Get the current PHY modulation. * May be @ref IEEE802154_PHY_MR_FSK, @ref IEEE802154_PHY_MR_OFDM, diff --git a/drivers/include/at86rf215.h b/drivers/include/at86rf215.h index b54d2178c3..b3362e6ced 100644 --- a/drivers/include/at86rf215.h +++ b/drivers/include/at86rf215.h @@ -56,6 +56,16 @@ typedef struct at86rf215_BBC_regs at86rf215_BBC_regs_t; */ typedef void (*at86rf215_batmon_cb_t)(void *arg); +/** + * @brief MR-O-QPSK chip rates (kChip/s) + */ +enum { + AT86RF215_FCHIP_100, + AT86RF215_FCHIP_200, + AT86RF215_FCHIP_1000, + AT86RF215_FCHIP_2000, +}; + /** * @brief Maximum possible packet size in byte */ @@ -100,6 +110,33 @@ typedef void (*at86rf215_batmon_cb_t)(void *arg); #define AT86RF215_DEFAULT_SUBGHZ_CHANNEL (CONFIG_IEEE802154_DEFAULT_SUBGHZ_CHANNEL) /** @} */ +/** + * @name Default PHY Mode + * @{ + */ +#ifndef AT86RF215_DEFAULT_PHY_MODE +#define AT86RF215_DEFAULT_PHY_MODE (IEEE802154_PHY_OQPSK) +#endif +/** @} */ + +/** + * @name Default MR-O-QPSK Chip Rate + * @{ + */ +#ifndef AT86RF215_DEFAULT_MR_OQPSK_CHIPS +#define AT86RF215_DEFAULT_MR_OQPSK_CHIPS (AT86RF215_FCHIP_1000) +#endif +/** @} */ + +/** + * @name Default MR-O-QPSK Rate Mode + * @{ + */ +#ifndef AT86RF215_DEFAULT_MR_OQPSK_RATE +#define AT86RF215_DEFAULT_MR_OQPSK_RATE (2) +#endif +/** @} */ + /** * @brief Default TX power (0dBm) */ From 504d02038d174ac860035c5bc2df6e97b2c7651c Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 21 Apr 2020 15:50:57 +0200 Subject: [PATCH 7/8] gnrc_netif: update PDU after changing PHY mode --- sys/net/gnrc/netif/gnrc_netif.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index 428c1e2711..597b6ff61d 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -363,6 +363,9 @@ int gnrc_netif_set_from_netdev(gnrc_netif_t *netif, case NETOPT_SRC_LEN: _update_l2addr_from_dev(netif); break; + case NETOPT_IEEE802154_PHY: + gnrc_netif_ipv6_init_mtu(netif); + break; case NETOPT_STATE: if (*((netopt_state_t *)opt->data) == NETOPT_STATE_RESET) { _configure_netdev(netif->dev); From 6ce0092982d350247fc22f5246b0303af58dd42c Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 28 Apr 2020 19:03:26 +0200 Subject: [PATCH 8/8] shell/sc_gnrc_netif: fix vera++ errors --- sys/shell/commands/sc_gnrc_netif.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sys/shell/commands/sc_gnrc_netif.c b/sys/shell/commands/sc_gnrc_netif.c index 3010e6f7c1..3441d06b1f 100644 --- a/sys/shell/commands/sc_gnrc_netif.c +++ b/sys/shell/commands/sc_gnrc_netif.c @@ -425,7 +425,6 @@ static unsigned _newline(unsigned threshold, unsigned line_thresh) return line_thresh; } - static unsigned _netif_list_flag(netif_t *iface, netopt_t opt, char *str, unsigned line_thresh) { @@ -693,7 +692,7 @@ static void _netif_list(netif_t *iface) #endif res = netif_get_opt(iface, NETOPT_SRC_LEN, 0, &u16, sizeof(u16)); if (res >= 0) { - printf("Source address length: %" PRIu16 , u16); + printf("Source address length: %" PRIu16, u16); line_thresh++; } line_thresh = _newline(0U, line_thresh); @@ -1014,7 +1013,7 @@ static int _netif_set_lw_key(netif_t *iface, netopt_t opt, char *key_str) size_t key_len = fmt_hex_bytes(key, key_str); size_t expected_len; - switch(opt) { + switch (opt) { case NETOPT_LORAWAN_APPKEY: case NETOPT_LORAWAN_APPSKEY: case NETOPT_LORAWAN_NWKSKEY: @@ -1375,7 +1374,7 @@ static uint8_t _get_prefix_len(char *addr) static int _netif_link(netif_t *iface, netopt_enable_t en) { - if(netif_set_opt(iface, NETOPT_LINK, 0, &en, sizeof(en)) < 0) { + if (netif_set_opt(iface, NETOPT_LINK, 0, &en, sizeof(en)) < 0) { printf("error: unable to set link %s\n", en == NETOPT_ENABLE ? "up" : "down"); return 1; }