diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 3903a60d5c..6e80cc3fe0 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -93,6 +93,7 @@ endif ifneq (,$(filter at86rf%, $(filter-out at86rf215%, $(USEMODULE)))) USEMODULE += at86rf2xx DEFAULT_MODULE += auto_init_at86rf2xx + DEFAULT_MODULE += netdev_ieee802154_oqpsk USEMODULE += xtimer USEMODULE += luid diff --git a/drivers/at86rf2xx/at86rf2xx_getset.c b/drivers/at86rf2xx/at86rf2xx_getset.c index ed7cd55ba9..cb3ae3f6c3 100644 --- a/drivers/at86rf2xx/at86rf2xx_getset.c +++ b/drivers/at86rf2xx/at86rf2xx_getset.c @@ -210,6 +210,48 @@ void at86rf2xx_set_page(at86rf2xx_t *dev, uint8_t page) #endif } +uint8_t at86rf2xx_get_phy_mode(at86rf2xx_t *dev) +{ +#ifdef MODULE_AT86RF212B + uint8_t ctrl2; + ctrl2 = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_CTRL_2); + if (ctrl2 & AT86RF2XX_TRX_CTRL_2_MASK__BPSK_OQPSK) { + return IEEE802154_PHY_OQPSK; + } else { + return IEEE802154_PHY_BPSK; + } +#else + (void) dev; + return IEEE802154_PHY_OQPSK; +#endif +} + +int at86rf2xx_set_rate(at86rf2xx_t *dev, uint8_t rate) +{ + uint8_t ctrl2; + + if (rate > 3) { + return -ERANGE; + } + + ctrl2 = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_CTRL_2); + ctrl2 &= ~AT86RF2XX_TRX_CTRL_2_MASK__OQPSK_DATA_RATE; + ctrl2 |= rate; + at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_CTRL_2, ctrl2); + + return 0; +} + +uint8_t at86rf2xx_get_rate(at86rf2xx_t *dev) +{ + uint8_t rate; + + rate = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_CTRL_2); + rate &= AT86RF2XX_TRX_CTRL_2_MASK__OQPSK_DATA_RATE; + + return rate; +} + uint16_t at86rf2xx_get_pan(const at86rf2xx_t *dev) { return dev->netdev.pan; diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index 076b5ae919..16303567bb 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -451,6 +451,20 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) } break; +#ifdef MODULE_NETDEV_IEEE802154_OQPSK + + case NETOPT_IEEE802154_PHY: + assert(max_len >= sizeof(int8_t)); + *(uint8_t *)val = at86rf2xx_get_phy_mode(dev); + return sizeof(uint8_t); + + case NETOPT_OQPSK_RATE: + assert(max_len >= sizeof(int8_t)); + *(uint8_t *)val = at86rf2xx_get_rate(dev); + return sizeof(uint8_t); + +#endif /* MODULE_NETDEV_IEEE802154_OQPSK */ + default: res = -ENOTSUP; break; @@ -638,6 +652,19 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) res = sizeof(int8_t); break; +#ifdef MODULE_NETDEV_IEEE802154_OQPSK + + case NETOPT_OQPSK_RATE: + assert(len <= sizeof(int8_t)); + if (at86rf2xx_set_rate(dev, *((const uint8_t *)val)) < 0) { + res = -EINVAL; + } else { + res = sizeof(uint8_t); + } + break; + +#endif /* MODULE_NETDEV_IEEE802154_OQPSK */ + default: break; } diff --git a/drivers/include/at86rf2xx.h b/drivers/include/at86rf2xx.h index 51c2a9dbcf..aefad4cd4a 100644 --- a/drivers/include/at86rf2xx.h +++ b/drivers/include/at86rf2xx.h @@ -374,6 +374,39 @@ uint8_t at86rf2xx_get_page(const at86rf2xx_t *dev); */ void at86rf2xx_set_page(at86rf2xx_t *dev, uint8_t page); +/** + * @brief Get the PHY mode of the given device + * + * @param[in,out] dev device to read from + * @return the currently set phy mode + */ +uint8_t at86rf2xx_get_phy_mode(at86rf2xx_t *dev); + +/** + * @brief Get the current O-QPSK rate mode of the PHY + * + * @param[in] dev device to read from + * + * @return the currenty set rate mode + */ +uint8_t at86rf2xx_get_rate(at86rf2xx_t *dev); + +/** + * @brief Set the current O-QPSK rate mode of the PHY + * rate modes > 0 are proprietary. + * + * rate 0: 250 kbit/s (IEEE mode) + * rate 1: 500 kbit/s + * rate 2: 1000 kbit/s (compatible with AT86RF215) + * rate 3: 2000 kbit/s + * + * @param[in] dev device to write to + * @param[in] rate the selected data rate mode (0-3) + * + * @return 0 on success, otherwise error value + */ +int at86rf2xx_set_rate(at86rf2xx_t *dev, uint8_t rate); + /** * @brief Get the configured PAN ID of the given device *