diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 3903a60d5c..7a833f4bc7 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -486,6 +486,7 @@ endif ifneq (,$(filter mrf24j40m%,$(USEMODULE))) USEMODULE += mrf24j40 + DEFAULT_MODULE += netdev_ieee802154_oqpsk ifndef CONFIG_KCONFIG_MODULE_MRF24J40 # all modules but mrf24j40ma have an external PA diff --git a/drivers/include/mrf24j40.h b/drivers/include/mrf24j40.h index 22ef45d69b..d6288bc6de 100644 --- a/drivers/include/mrf24j40.h +++ b/drivers/include/mrf24j40.h @@ -360,6 +360,27 @@ void mrf24j40_set_option(mrf24j40_t *dev, uint16_t option, bool state); */ void mrf24j40_set_state(mrf24j40_t *dev, uint8_t state); +/** + * @brief Enable or disable proprietary Turbo Mode. + * + * Turbo mode is only compatible with other mrf24j40 chips. + * + * turbo off: 250 kbit/s (IEEE mode) + * turbo on: 625 kbit/s + * + * @param[in] dev device to change state of + * @param[in] enable turbo mode control + */ +void mrf24j40_set_turbo(mrf24j40_t *dev, bool enable); + +/** + * @brief Query the state of the turbo mode + * + * @param[in] dev device to query + * @return true if Turbo Mode is enabled + */ +bool mrf24j40_get_turbo(mrf24j40_t *dev); + /** * @brief Put in sleep mode * diff --git a/drivers/mrf24j40/mrf24j40_getset.c b/drivers/mrf24j40/mrf24j40_getset.c index 07aaf79418..304bc3644d 100644 --- a/drivers/mrf24j40/mrf24j40_getset.c +++ b/drivers/mrf24j40/mrf24j40_getset.c @@ -121,6 +121,16 @@ static const uint8_t RSSI_value[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static void mrf24j40_baseband_reset(mrf24j40_t *dev) +{ + uint8_t softrst; + + mrf24j40_reg_write_short(dev, MRF24J40_REG_SOFTRST, MRF24J40_SOFTRST_RSTBB); + do { + softrst = mrf24j40_reg_read_short(dev, MRF24J40_REG_SOFTRST); + } while (softrst != 0); /* wait until soft-reset has finished */ +} + uint16_t mrf24j40_get_addr_short(mrf24j40_t *dev) { network_uint16_t naddr; @@ -329,6 +339,32 @@ void mrf24j40_set_cca_threshold(mrf24j40_t *dev, int8_t value) mrf24j40_reg_write_short(dev, MRF24J40_REG_CCAEDTH, RSSI_value[value]); } +void mrf24j40_set_turbo(mrf24j40_t *dev, bool on) +{ + uint8_t tmp; + static const uint8_t cfg[2][2] = { + {0xD0, 0x80}, /* IEEE mode */ + {0x30, 0x40} /* Turbo mode */ + }; + + mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG0, on); + + /* Set Preamble Search Energy Valid Threshold */ + tmp = mrf24j40_reg_read_short(dev, MRF24J40_REG_BBREG3) & 0xF; + mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG3, tmp | cfg[on][0]); + + /* Set Carrier Sense Threshold */ + tmp = mrf24j40_reg_read_short(dev, MRF24J40_REG_BBREG4) & 0x1F; + mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG4, tmp | cfg[on][1]); + + mrf24j40_baseband_reset(dev); +} + +bool mrf24j40_get_turbo(mrf24j40_t *dev) +{ + return mrf24j40_reg_read_short(dev, MRF24J40_REG_BBREG0); +} + void mrf24j40_set_option(mrf24j40_t *dev, uint16_t option, bool state) { uint8_t tmp; diff --git a/drivers/mrf24j40/mrf24j40_netdev.c b/drivers/mrf24j40/mrf24j40_netdev.c index 74d61e491e..5604f2854f 100644 --- a/drivers/mrf24j40/mrf24j40_netdev.c +++ b/drivers/mrf24j40/mrf24j40_netdev.c @@ -330,6 +330,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 = IEEE802154_PHY_OQPSK; + return sizeof(uint8_t); + + case NETOPT_OQPSK_RATE: + assert(max_len >= sizeof(int8_t)); + *(uint8_t *)val = mrf24j40_get_turbo(dev); + return sizeof(uint8_t); + +#endif /* MODULE_NETDEV_IEEE802154_OQPSK */ + default: /* try netdev settings */ res = netdev_ieee802154_get((netdev_ieee802154_t *)netdev, opt, @@ -524,6 +538,16 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) } break; +#ifdef MODULE_NETDEV_IEEE802154_OQPSK + + case NETOPT_OQPSK_RATE: + res = !!*(uint8_t *)val; + mrf24j40_set_turbo(dev, res); + res = sizeof(uint8_t); + break; + +#endif /* MODULE_NETDEV_IEEE802154_OQPSK */ + default: break; }