diff --git a/sys/include/net/ieee802154.h b/sys/include/net/ieee802154.h index 6769d5b3db..ddfaad3437 100644 --- a/sys/include/net/ieee802154.h +++ b/sys/include/net/ieee802154.h @@ -125,6 +125,13 @@ extern "C" { */ #define IEEE802154_MR_OFDM_SYMBOL_TIME_US (120) +/** + * @brief Symbol time for IEEE 802.15.4 MR-FSK in µs + * + * symbol time is always 20 µs for MR-FSK (table 0, pg. 7) + */ +#define IEEE802154_MR_FSK_SYMBOL_TIME_US (20) + /** * @brief value of measured power when RSSI is zero. * @@ -190,11 +197,23 @@ typedef enum { /** * @brief 802.15.4 forward error correction schemes */ -enum { +typedef enum { IEEE802154_FEC_NONE, /**< no forward error correction */ IEEE802154_FEC_NRNSC, /**< non-recursive and non-systematic code */ IEEE802154_FEC_RSC /**< recursive and systematic code */ -}; +} ieee802154_mr_fsk_fec_t; + +/** + * @brief 802.15.4 MR-FSK symbol rates + */ +typedef enum { + IEEE802154_MR_FSK_SRATE_50K, /**< 50k Symbols/s */ + IEEE802154_MR_FSK_SRATE_100K, /**< 100k Symbols/s */ + IEEE802154_MR_FSK_SRATE_150K, /**< 150k Symbols/s */ + IEEE802154_MR_FSK_SRATE_200K, /**< 200k Symbols/s */ + IEEE802154_MR_FSK_SRATE_300K, /**< 300k Symbols/s */ + IEEE802154_MR_FSK_SRATE_400K, /**< 400k Symbols/s */ +} ieee802154_mr_fsk_srate_t; /** * @brief 802.15.4 MR-OQPSK chip rates @@ -206,6 +225,32 @@ typedef enum { IEEE802154_MR_OQPSK_CHIPS_2000, /**< 2000 kChip/s */ } ieee802154_mr_oqpsk_chips_t; +/** + * @brief Get the minimum pramble length for a given symbol rate + * + * From IEEE 802.15.4g Table 6-64 + * + * @param[in] srate symbol rate + * @return preamble length in bytes + */ +static inline uint8_t ieee802154_mr_fsk_plen(ieee802154_mr_fsk_srate_t srate) +{ + switch (srate) { + case IEEE802154_MR_FSK_SRATE_50K: + return 2; + case IEEE802154_MR_FSK_SRATE_100K: + return 3; + case IEEE802154_MR_FSK_SRATE_150K: + case IEEE802154_MR_FSK_SRATE_200K: + case IEEE802154_MR_FSK_SRATE_300K: + return 8; + case IEEE802154_MR_FSK_SRATE_400K: + return 10; + } + + return 0; +} + /** * @brief Special address definitions * @{ @@ -302,6 +347,34 @@ extern const uint8_t ieee802154_addr_bcast[IEEE802154_ADDR_BCAST_LEN]; #define CONFIG_IEEE802154_MR_OFDM_DEFAULT_SCHEME (2U) #endif +/** + * @brief IEEE802.15.4 MR-FSK default symbol rate + */ +#ifndef CONFIG_IEEE802154_MR_FSK_DEFAULT_SRATE +#define CONFIG_IEEE802154_MR_FSK_DEFAULT_SRATE IEEE802154_MR_FSK_SRATE_200K +#endif + +/** + * @brief IEEE802.15.4 MR-FSK default modulation index, fraction of 64 + */ +#ifndef CONFIG_IEEE802154_MR_FSK_DEFAULT_MOD_IDX +#define CONFIG_IEEE802154_MR_FSK_DEFAULT_MOD_IDX (64U) +#endif + +/** + * @brief IEEE802.15.4 MR-FSK default modulation order + */ +#ifndef CONFIG_IEEE802154_MR_FSK_DEFAULT_MOD_ORD +#define CONFIG_IEEE802154_MR_FSK_DEFAULT_MOD_ORD (2U) +#endif + +/** + * @brief IEEE802.15.4 MR-FSK default error correction mode + */ +#ifndef CONFIG_IEEE802154_MR_FSK_DEFAULT_FEC +#define CONFIG_IEEE802154_MR_FSK_DEFAULT_FEC IEEE802154_FEC_NONE +#endif + /** * @brief IEEE802.15.4 default PANID */ diff --git a/sys/include/net/ieee802154/radio.h b/sys/include/net/ieee802154/radio.h index 106a07ccdc..8f9e0ca7a1 100644 --- a/sys/include/net/ieee802154/radio.h +++ b/sys/include/net/ieee802154/radio.h @@ -477,6 +477,17 @@ typedef struct { uint8_t scheme; /**< Modulation & Coding Scheme */ } ieee802154_mr_odmf_conf_t; +/** + * @brief extension for IEEE 802.15.4g MR-FSK PHY + */ +typedef struct { + ieee802154_phy_conf_t super; /**< common settings */ + ieee802154_mr_fsk_srate_t srate; /**< symbol rate */ + uint8_t mod_ord; /**< modulation order, 2 or 4 */ + uint8_t mod_idx; /**< modulation index */ + ieee802154_mr_fsk_fec_t fec; /**< forward error correction */ +} ieee802154_mr_fsk_conf_t; + /** * @brief IEEE 802.15.4 radio operations */ diff --git a/sys/net/link_layer/ieee802154/submac.c b/sys/net/link_layer/ieee802154/submac.c index 16e88b4f70..9f95c3b258 100644 --- a/sys/net/link_layer/ieee802154/submac.c +++ b/sys/net/link_layer/ieee802154/submac.c @@ -498,6 +498,7 @@ static inline uint8_t _mr_oqpsk_ack_psdu_duration_syms(uint8_t chips, uint8_t mo return (Npsdu + Ns/2) / Ns + (Npsdu + 8 * Ns) / (16 * Ns); } +MAYBE_UNUSED static inline uint16_t _mr_oqpsk_ack_timeout_us(const ieee802154_mr_oqpks_conf_t *conf) { /* see 802.15.4g-2012, p. 30 */ @@ -510,6 +511,7 @@ static inline uint16_t _mr_oqpsk_ack_timeout_us(const ieee802154_mr_oqpks_conf_t + IEEE802154G_ATURNAROUNDTIME_US; } +MAYBE_UNUSED static inline uint16_t _mr_oqpsk_csma_backoff_period_us(const ieee802154_mr_oqpks_conf_t *conf) { return _mr_oqpsk_cca_duration_syms(conf->chips) * _mr_oqpsk_symbol_duration_us(conf->chips) @@ -546,6 +548,7 @@ static inline uint16_t _mr_ofdm_csma_backoff_period_us(const ieee802154_mr_odmf_ + IEEE802154G_ATURNAROUNDTIME_US; } +MAYBE_UNUSED static inline uint16_t _mr_ofdm_ack_timeout_us(const ieee802154_mr_odmf_conf_t *conf) { return _mr_ofdm_csma_backoff_period_us(conf) @@ -553,6 +556,47 @@ static inline uint16_t _mr_ofdm_ack_timeout_us(const ieee802154_mr_odmf_conf_t * + _mr_ofdm_frame_duration(conf->option, conf->scheme, IEEE802154_ACK_FRAME_LEN); } +/* + * MR-FSK timing calculations + * + * The standard unfortunately does not list the formula, instead it has to be pieced together + * from scattered information and tables in the IEEE 802.15.4 document - may contain errors. + */ + +MAYBE_UNUSED +static inline uint16_t _mr_fsk_csma_backoff_period_us(const ieee802154_mr_fsk_conf_t *conf) +{ + (void)conf; + + return IEEE802154_CCA_DURATION_IN_SYMBOLS * IEEE802154_MR_FSK_SYMBOL_TIME_US + + IEEE802154G_ATURNAROUNDTIME_US; +} + +MAYBE_UNUSED +static inline uint16_t _mr_fsk_ack_timeout_us(const ieee802154_mr_fsk_conf_t *conf) +{ + uint8_t ack_len = IEEE802154_ACK_FRAME_LEN; + uint8_t fsk_pl = ieee802154_mr_fsk_plen(conf->srate); + + /* PHR uses same data rate as PSDU */ + ack_len += 2; + + /* 4-FSK doubles data rate */ + if (conf->mod_ord == 4) { + ack_len /= 2; + } + + /* forward error correction halves data rate */ + if (conf->fec) { + ack_len *= 2; + } + + return _mr_fsk_csma_backoff_period_us(conf) + + IEEE802154G_ATURNAROUNDTIME_US + /* long Preamble + SFD; SFD=2 */ + + ((fsk_pl * 8 + 2) + ack_len) * 8 * IEEE802154_MR_FSK_SYMBOL_TIME_US; +} + static int ieee802154_submac_config_phy(ieee802154_submac_t *submac, const ieee802154_phy_conf_t *conf) { @@ -572,6 +616,12 @@ static int ieee802154_submac_config_phy(ieee802154_submac_t *submac, submac->ack_timeout_us = _mr_ofdm_ack_timeout_us((void *)conf); submac->csma_backoff_us = _mr_ofdm_csma_backoff_period_us((void *)conf); break; +#endif +#ifdef MODULE_NETDEV_IEEE802154_MR_FSK + case IEEE802154_PHY_MR_FSK: + submac->ack_timeout_us = _mr_fsk_ack_timeout_us((void *)conf); + submac->csma_backoff_us = _mr_fsk_csma_backoff_period_us((void *)conf); + break; #endif case IEEE802154_PHY_NO_OP: case IEEE802154_PHY_DISABLED: @@ -658,6 +708,9 @@ int ieee802154_submac_init(ieee802154_submac_t *submac, const network_uint16_t * #endif #ifdef MODULE_NETDEV_IEEE802154_MR_OFDM ieee802154_mr_odmf_conf_t mr_ofdm; +#endif +#ifdef MODULE_NETDEV_IEEE802154_MR_FSK + ieee802154_mr_fsk_conf_t mr_fsk; #endif } conf; @@ -673,6 +726,14 @@ int ieee802154_submac_init(ieee802154_submac_t *submac, const network_uint16_t * conf.mr_ofdm.scheme = CONFIG_IEEE802154_MR_OFDM_DEFAULT_SCHEME; } #endif +#ifdef MODULE_NETDEV_IEEE802154_MR_FSK + if (submac->phy_mode == IEEE802154_PHY_MR_FSK) { + conf.mr_fsk.srate = CONFIG_IEEE802154_MR_FSK_DEFAULT_SRATE; + conf.mr_fsk.mod_ord = CONFIG_IEEE802154_MR_FSK_DEFAULT_MOD_ORD; + conf.mr_fsk.mod_idx = CONFIG_IEEE802154_MR_FSK_DEFAULT_MOD_IDX; + conf.mr_fsk.fec = CONFIG_IEEE802154_MR_FSK_DEFAULT_FEC; + } +#endif conf.super.phy_mode = submac->phy_mode; conf.super.channel = submac->channel_num;