diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index 258011cd9..a1ba95d72 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -164,15 +164,17 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) (void)tmp; if (info != NULL) { + uint8_t rssi = 0; netdev_ieee802154_rx_info_t *radio_info = info; at86rf2xx_fb_read(dev, &(radio_info->lqi), 1); #ifndef MODULE_AT86RF231 - at86rf2xx_fb_read(dev, &(radio_info->rssi), 1); + at86rf2xx_fb_read(dev, &(rssi), 1); at86rf2xx_fb_stop(dev); #else at86rf2xx_fb_stop(dev); - radio_info->rssi = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_ED_LEVEL); + rssi = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_ED_LEVEL); #endif + radio_info->rssi = RSSI_BASE_VAL + rssi; } else { at86rf2xx_fb_stop(dev); diff --git a/drivers/cc110x/cc110x-netdev.c b/drivers/cc110x/cc110x-netdev.c index 9f9f8989c..5db238dbd 100644 --- a/drivers/cc110x/cc110x-netdev.c +++ b/drivers/cc110x/cc110x-netdev.c @@ -27,6 +27,7 @@ #include "cc110x-netdev.h" #include "cc110x-internal.h" #include "cc110x-interface.h" +#include "cc110x-defines.h" #include "net/eui64.h" #include "periph/gpio.h" @@ -61,7 +62,7 @@ static int _recv(netdev_t *dev, void *buf, size_t len, void *info) if (info != NULL) { netdev_cc110x_rx_info_t *cc110x_info = info; - cc110x_info->rssi = cc110x->pkt_buf.rssi; + cc110x_info->rssi = (int16_t)cc110x->pkt_buf.rssi/2 - CC110X_RSSI_OFFSET; cc110x_info->lqi = cc110x->pkt_buf.lqi; } return cc110x_pkt->length; diff --git a/drivers/cc110x/include/cc110x-defines.h b/drivers/cc110x/include/cc110x-defines.h index ee5577a05..069076b58 100644 --- a/drivers/cc110x/include/cc110x-defines.h +++ b/drivers/cc110x/include/cc110x-defines.h @@ -34,6 +34,15 @@ extern "C" { */ #define VARIABLE_PKTLEN (0x01) +/** + * @brief RSSI calculation offset. + * + * The cc1101 has 74 as a RSSI offset. The CC1100E has a + * slightly larger offset of 75 to 79 (not implemented here). + * With those devices we thus get a slightly optimistic result. + */ +#define CC110X_RSSI_OFFSET (74) + /** * @name Bitmasks for reading out status register values * @{ diff --git a/drivers/cc2420/cc2420.c b/drivers/cc2420/cc2420.c index bb7ce3d5c..2b4802772 100644 --- a/drivers/cc2420/cc2420.c +++ b/drivers/cc2420/cc2420.c @@ -197,8 +197,8 @@ int cc2420_rx(cc2420_t *dev, uint8_t *buf, size_t max_len, void *info) DEBUG("cc2420: recv: reading %i byte of the packet\n", (int)len); cc2420_fifo_read(dev, buf, len); - uint8_t rssi; - cc2420_fifo_read(dev, &rssi, 1); + int8_t rssi; + cc2420_fifo_read(dev, (uint8_t*)&rssi, 1); DEBUG("cc2420: recv: RSSI is %i\n", (int)rssi); /* fetch and check if CRC_OK bit (MSB) is set */ @@ -208,6 +208,11 @@ int cc2420_rx(cc2420_t *dev, uint8_t *buf, size_t max_len, void *info) /* drop the corrupted frame from the RXFIFO */ len = 0; } + if (info != NULL) { + netdev_ieee802154_rx_info_t *radio_info = info; + radio_info->rssi = CC2420_RSSI_OFFSET + rssi; + radio_info->lqi = crc_corr & CC2420_CRCCOR_COR_MASK; + } /* finally flush the FIFO */ cc2420_strobe(dev, CC2420_STROBE_FLUSHRX); diff --git a/drivers/cc2420/include/cc2420_registers.h b/drivers/cc2420/include/cc2420_registers.h index 23cba2cee..00725aa1f 100644 --- a/drivers/cc2420/include/cc2420_registers.h +++ b/drivers/cc2420/include/cc2420_registers.h @@ -190,6 +190,14 @@ enum { #define CC2420_MDMCTRL0_PREAMBLE_3B (0x0002) /** @} */ +/** + * @brief CRC/Correlation bit masks + * @{ + */ +#define CC2420_CRCCOR_CRC_MASK (0x80) +#define CC2420_CRCCOR_COR_MASK (0x7F) +/** @} */ + /** * @name Transmit control register bitfields * @{ diff --git a/drivers/include/cc2420.h b/drivers/include/cc2420.h index cee30a128..a2d6f77be 100644 --- a/drivers/include/cc2420.h +++ b/drivers/include/cc2420.h @@ -61,6 +61,11 @@ extern "C" { #define CC2420_TXPOWER_DEFAULT (IEEE802154_DEFAULT_TXPOWER) /** @} */ +/** + * @brief RSSI offset + */ +#define CC2420_RSSI_OFFSET (-45) + /** * @brief A couple of return values used in this driver */ diff --git a/drivers/include/mrf24j40.h b/drivers/include/mrf24j40.h index 8cf6a59ff..6b5427df1 100644 --- a/drivers/include/mrf24j40.h +++ b/drivers/include/mrf24j40.h @@ -368,6 +368,14 @@ void mrf24j40_reset_state_machine(mrf24j40_t *dev); */ void mrf24j40_software_reset(mrf24j40_t *dev); +/** + * @brief Convert scalar from mrf24j40 RSSI to dBm + * + * @param[in] value value to convert to dBm + * @return converted value in dBm + */ +int8_t mrf24j40_dbm_from_reg(uint8_t value); + /** * @brief Prepare for sending of data * diff --git a/drivers/include/net/netdev.h b/drivers/include/net/netdev.h index 47c06b487..51910edeb 100644 --- a/drivers/include/net/netdev.h +++ b/drivers/include/net/netdev.h @@ -246,7 +246,7 @@ typedef enum { * May be different for certain radios. */ struct netdev_radio_rx_info { - uint8_t rssi; /**< RSSI of a received packet */ + int16_t rssi; /**< RSSI of a received packet in dBm */ uint8_t lqi; /**< LQI of a received packet */ }; diff --git a/drivers/kw2xrf/include/kw2xrf_getset.h b/drivers/kw2xrf/include/kw2xrf_getset.h index 0b02cc282..5ffdf29d8 100644 --- a/drivers/kw2xrf/include/kw2xrf_getset.h +++ b/drivers/kw2xrf/include/kw2xrf_getset.h @@ -160,7 +160,7 @@ uint8_t kw2xrf_get_cca_mode(kw2xrf_t *dev); * * @return deduced RSSI in dBm */ -uint32_t kw2xrf_get_rssi(uint32_t value); +int16_t kw2xrf_get_rssi(uint32_t value); /** * @brief Get state of a given device diff --git a/drivers/kw2xrf/kw2xrf_getset.c b/drivers/kw2xrf/kw2xrf_getset.c index 71c1fe532..b3bd2f07e 100644 --- a/drivers/kw2xrf/kw2xrf_getset.c +++ b/drivers/kw2xrf/kw2xrf_getset.c @@ -346,7 +346,7 @@ uint8_t kw2xrf_get_cca_mode(kw2xrf_t *dev) return (tmp & MKW2XDM_PHY_CTRL4_CCATYPE_MASK) >> MKW2XDM_PHY_CTRL4_CCATYPE_SHIFT; } -uint32_t kw2xrf_get_rssi(uint32_t value) +int16_t kw2xrf_get_rssi(uint32_t value) { /* Get rssi (Received Signal Strength Indicator, unit is dBm) * from lqi (Link Quality Indicator) value. @@ -361,7 +361,7 @@ uint32_t kw2xrf_get_rssi(uint32_t value) */ uint32_t a = (uint32_t)(295.4 * 65536 / 2.84); uint32_t b = (uint32_t)(65536 / 2.84); - return (a - (b * value)) >> 16; + return ((b * value) - a) >> 16; } void kw2xrf_set_option(kw2xrf_t *dev, uint16_t option, bool state) diff --git a/drivers/kw2xrf/kw2xrf_netdev.c b/drivers/kw2xrf/kw2xrf_netdev.c index 5511b5ea2..e0a876711 100644 --- a/drivers/kw2xrf/kw2xrf_netdev.c +++ b/drivers/kw2xrf/kw2xrf_netdev.c @@ -169,7 +169,7 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) if (info != NULL) { netdev_ieee802154_rx_info_t *radio_info = info; radio_info->lqi = ((uint8_t*)buf)[pkt_len]; - radio_info->rssi = (uint8_t)kw2xrf_get_rssi(radio_info->lqi); + radio_info->rssi = kw2xrf_get_rssi(radio_info->lqi); } /* skip FCS and LQI */ diff --git a/drivers/mrf24j40/mrf24j40_getset.c b/drivers/mrf24j40/mrf24j40_getset.c index b53206071..92a19f393 100644 --- a/drivers/mrf24j40/mrf24j40_getset.c +++ b/drivers/mrf24j40/mrf24j40_getset.c @@ -74,38 +74,38 @@ static const uint8_t dbm_to_tx_pow[] = { 0x00, 0x10, 0x18, 0x20, 0x28, 0x30, 0x3 0xc0, 0xd0, 0xd8, 0xe0, 0xe8, 0xf0, 0xf8 }; /* take a look onto datasheet table 3-8 */ -static const int8_t dBm_value[] = { 95, 89, 88, 88, 87, 87, 87, 87, \ - 86, 86, 86, 86, 85, 85, 85, 85, \ - 84, 84, 84, 84, 84, 84, 83, 83, \ - 83, 83, 82, 82, 82, 82, 81, 81, \ - 81, 81, 81, 80, 80, 80, 80, 80, \ - 80, 79, 79, 79, 79, 79, 78, 78, \ - 78, 78, 78, 77, 77, 77, 77, 77, \ - 76, 76, 76, 76, 76, 75, 75, 75, \ - 75, 75, 75, 74, 74, 74, 74, 73, \ - 73, 73, 73, 73, 72, 72, 72, 72, \ - 72, 71, 71, 71, 71, 71, 70, 70, \ - 70, 70, 70, 70, 70, 69, 69, 69, \ - 69, 69, 68, 68, 68, 68, 68, 68, \ - 68, 67, 67, 67, 67, 66, 66, 66, \ - 66, 66, 66, 65, 65, 65, 65, 65, \ - 64, 64, 64, 64, 63, 63, 63, 63, \ - 62, 62, 62, 62, 61, 61, 61, 61, \ - 60, 60, 60, 60, 60, 59, 59, 59, \ - 59, 59, 58, 58, 58, 58, 58, 57, \ - 57, 57, 57, 57, 57, 56, 56, 56, \ - 56, 56, 56, 56, 55, 55, 55, 55, \ - 54, 54, 54, 54, 54, 54, 53, 53, \ - 53, 53, 53, 53, 53, 52, 52, 52, \ - 52, 52, 52, 51, 51, 51, 51, 51, \ - 50, 50, 50, 50, 50, 49, 49, 49, \ - 49, 49, 48, 48, 48, 48, 47, 47, \ - 47, 47, 47, 46, 46, 46, 46, 45, \ - 45, 45, 45, 44, 44, 44, 44, 44, \ - 43, 43, 43, 42, 42, 42, 42, 41, \ - 41, 41, 41, 41, 41, 40, 40, 40, \ - 40, 40, 39, 39, 39, 39, 39, 38, \ - 38, 38, 38, 37, 37, 37, 36, 30 }; +static const int8_t dBm_value[] = { -90, -89, -88, -88, -87, -87, -87, -87, \ + -86, -86, -86, -86, -85, -85, -85, -85, \ + -84, -84, -84, -84, -84, -84, -83, -83, \ + -83, -83, -82, -82, -82, -82, -81, -81, \ + -81, -81, -81, -80, -80, -80, -80, -80, \ + -80, -79, -79, -79, -79, -79, -78, -78, \ + -78, -78, -78, -77, -77, -77, -77, -77, \ + -76, -76, -76, -76, -76, -75, -75, -75, \ + -75, -75, -75, -74, -74, -74, -74, -73, \ + -73, -73, -73, -73, -72, -72, -72, -72, \ + -72, -71, -71, -71, -71, -71, -70, -70, \ + -70, -70, -70, -70, -70, -69, -69, -69, \ + -69, -69, -68, -68, -68, -68, -68, -68, \ + -68, -67, -67, -67, -67, -66, -66, -66, \ + -66, -66, -66, -65, -65, -65, -65, -65, \ + -64, -64, -64, -64, -63, -63, -63, -63, \ + -62, -62, -62, -62, -61, -61, -61, -61, \ + -60, -60, -60, -60, -60, -59, -59, -59, \ + -59, -59, -58, -58, -58, -58, -58, -57, \ + -57, -57, -57, -57, -57, -56, -56, -56, \ + -56, -56, -56, -56, -55, -55, -55, -55, \ + -54, -54, -54, -54, -54, -54, -53, -53, \ + -53, -53, -53, -53, -53, -52, -52, -52, \ + -52, -52, -52, -51, -51, -51, -51, -51, \ + -50, -50, -50, -50, -50, -49, -49, -49, \ + -49, -49, -48, -48, -48, -48, -47, -47, \ + -47, -47, -47, -46, -46, -46, -46, -45, \ + -45, -45, -45, -44, -44, -44, -44, -44, \ + -43, -43, -43, -42, -42, -42, -42, -41, \ + -41, -41, -41, -41, -41, -40, -40, -40, \ + -40, -40, -39, -39, -39, -39, -39, -38, \ + -38, -38, -38, -37, -37, -37, -36, -35 }; /* take a look onto datasheet table 3-8 */ static const uint8_t RSSI_value[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \ @@ -488,3 +488,8 @@ void mrf24j40_software_reset(mrf24j40_t *dev) softrst = mrf24j40_reg_read_short(dev, MRF24J40_REG_SOFTRST); } while (softrst != 0); /* wait until soft-reset has finished */ } + +int8_t mrf24j40_dbm_from_reg(uint8_t value) +{ + return dBm_value[value]; +} diff --git a/drivers/mrf24j40/mrf24j40_netdev.c b/drivers/mrf24j40/mrf24j40_netdev.c index c0c74a9bb..02598c1b4 100644 --- a/drivers/mrf24j40/mrf24j40_netdev.c +++ b/drivers/mrf24j40/mrf24j40_netdev.c @@ -156,9 +156,11 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) if (info != NULL) { netdev_ieee802154_rx_info_t *radio_info = info; + uint8_t rssi_scalar = 0; /* Read LQI and RSSI values from the RX fifo */ mrf24j40_rx_fifo_read(dev, phr + 1, &(radio_info->lqi), 1); - mrf24j40_rx_fifo_read(dev, phr + 2, &(radio_info->rssi), 1); + mrf24j40_rx_fifo_read(dev, phr + 2, &(rssi_scalar), 1); + radio_info->rssi = mrf24j40_dbm_from_reg(rssi_scalar); } /* Turn on reception of packets off the air */ diff --git a/sys/include/net/gnrc/netif/hdr.h b/sys/include/net/gnrc/netif/hdr.h index b1e101efd..b4ab577f9 100644 --- a/sys/include/net/gnrc/netif/hdr.h +++ b/sys/include/net/gnrc/netif/hdr.h @@ -85,7 +85,7 @@ typedef struct { uint8_t dst_l2addr_len; /**< length of l2 destination address in byte */ kernel_pid_t if_pid; /**< PID of network interface */ uint8_t flags; /**< flags as defined above */ - uint8_t rssi; /**< rssi of received packet (optional) */ + int16_t rssi; /**< rssi of received packet in dBm (optional) */ uint8_t lqi; /**< lqi of received packet (optional) */ } gnrc_netif_hdr_t; diff --git a/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c b/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c index 06fd418ce..275ea3170 100644 --- a/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c +++ b/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c @@ -23,7 +23,7 @@ void gnrc_netif_hdr_print(gnrc_netif_hdr_t *hdr) char addr_str[GNRC_NETIF_HDR_L2ADDR_PRINT_LEN]; printf("if_pid: %u ", (unsigned) hdr->if_pid); - printf("rssi: %u ", (unsigned) hdr->rssi); + printf("rssi: %d ", (signed) hdr->rssi); printf("lqi: %u\n", (unsigned) hdr->lqi); printf("flags: ");