mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 05:32:45 +01:00
Merge pull request #13912 from benpicco/at86rf215-mr-qpsk
drivers/at86rf215: implement MR-O-QPSK
This commit is contained in:
commit
80b300289d
@ -70,6 +70,11 @@ ifneq (,$(filter at86rf215%,$(USEMODULE)))
|
||||
DEFAULT_MODULE += auto_init_at86rf215
|
||||
DEFAULT_MODULE += at86rf215_subghz
|
||||
|
||||
DEFAULT_MODULE += netdev_ieee802154_multimode
|
||||
|
||||
DEFAULT_MODULE += netdev_ieee802154_oqpsk
|
||||
DEFAULT_MODULE += netdev_ieee802154_mr_oqpsk
|
||||
|
||||
ifeq (,$(filter at86rf215m,$(USEMODULE)))
|
||||
DEFAULT_MODULE += at86rf215_24ghz
|
||||
endif
|
||||
|
@ -17,7 +17,6 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#include "luid.h"
|
||||
#include "byteorder.h"
|
||||
#include "net/ieee802154.h"
|
||||
@ -145,8 +144,13 @@ if (!IS_ACTIVE(CONFIG_AT86RF215_USE_CLOCK_OUTPUT)){
|
||||
|
||||
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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
@ -384,6 +388,35 @@ 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;
|
||||
|
||||
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;
|
||||
@ -528,6 +561,77 @@ 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;
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,105 @@ 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,
|
||||
* @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
|
||||
|
@ -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)
|
||||
*/
|
||||
@ -119,6 +156,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
|
||||
* @{
|
||||
|
@ -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:
|
||||
|
@ -62,6 +62,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
|
||||
|
@ -94,7 +94,38 @@ 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 */
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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 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
|
||||
|
@ -651,6 +651,31 @@ typedef enum {
|
||||
*/
|
||||
NETOPT_LORAWAN_MIN_RX_SYMBOL,
|
||||
|
||||
/**
|
||||
* @brief (uint8_t) 802.15.4 PHY mode
|
||||
*/
|
||||
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
|
||||
*/
|
||||
|
@ -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",
|
||||
|
@ -374,6 +374,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);
|
||||
|
@ -18,6 +18,7 @@
|
||||
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -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)
|
||||
@ -370,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)
|
||||
{
|
||||
@ -478,7 +532,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));
|
||||
@ -493,7 +547,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) {
|
||||
@ -603,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);
|
||||
@ -781,6 +870,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 <if_id> 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)
|
||||
{
|
||||
@ -894,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:
|
||||
@ -1162,7 +1281,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);
|
||||
}
|
||||
@ -1237,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user