diff --git a/drivers/cc110x/cc110x_netdev.c b/drivers/cc110x/cc110x_netdev.c index 50ae5ddb2c..2f69dfa823 100644 --- a/drivers/cc110x/cc110x_netdev.c +++ b/drivers/cc110x/cc110x_netdev.c @@ -514,6 +514,27 @@ static int cc110x_get_iid(cc110x_t *dev, eui64_t *iid) return sizeof(eui64_t); } +/** + * @brief Checks if the CC110x's address filter is disabled + * @param dev Transceiver to check if in promiscuous mode + * @param dest Store the result here + * + * @return Returns the size of @ref netopt_enable_t to confirm with the API + * in @ref netdev_driver_t::get + */ +static int cc110x_get_promiscuous_mode(cc110x_t *dev, netopt_enable_t *dest) +{ + if (cc110x_acquire(dev) != SPI_OK) { + return -EIO; + } + + uint8_t pktctrl1; + cc110x_read(dev, CC110X_REG_PKTCTRL1, &pktctrl1); + *dest = ((pktctrl1 & CC110X_PKTCTRL1_GET_ADDR_MODE) == CC110X_PKTCTRL1_ADDR_ALL); + cc110x_release(dev); + return sizeof(netopt_enable_t); +} + static int cc110x_get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len) { @@ -555,6 +576,9 @@ static int cc110x_get(netdev_t *netdev, netopt_t opt, assert(max_len == sizeof(uint16_t)); *((uint16_t *)val) = dbm_from_tx_power[dev->tx_power]; return sizeof(uint16_t); + case NETOPT_PROMISCUOUSMODE: + assert(max_len == sizeof(netopt_enable_t)); + return cc110x_get_promiscuous_mode(dev, val); default: return -ENOTSUP; } @@ -578,6 +602,32 @@ static int cc110x_set_addr(cc110x_t *dev, uint8_t addr) return 1; } +/** + * @brief Enables/disables the CC110x's address filter + * @param dev Transceiver to turn promiscuous mode on/off + * @param enable Whether to enable or disable promiscuous mode + * + * @return Returns the size of @ref netopt_enable_t to confirm with the API + * in @ref netdev_driver_t::set + */ +static int cc110x_set_promiscuous_mode(cc110x_t *dev, netopt_enable_t enable) +{ + if (cc110x_acquire(dev) != SPI_OK) { + return -EIO; + } + + uint8_t pktctrl1 = CC110X_PKTCTRL1_VALUE; + if (enable == NETOPT_ENABLE) { + pktctrl1 |= CC110X_PKTCTRL1_ADDR_ALL; + } + else { + pktctrl1 |= CC110X_PKTCTRL1_ADDR_MATCH; + } + cc110x_write(dev, CC110X_REG_PKTCTRL1, pktctrl1); + cc110x_release(dev); + return sizeof(netopt_enable_t); +} + static int cc110x_set(netdev_t *netdev, netopt_t opt, const void *val, size_t len) { @@ -616,6 +666,9 @@ static int cc110x_set(netdev_t *netdev, netopt_t opt, } } return sizeof(uint16_t); + case NETOPT_PROMISCUOUSMODE: + assert(len == sizeof(netopt_enable_t)); + return cc110x_set_promiscuous_mode(dev, *((const netopt_enable_t *)val)); default: return -ENOTSUP; } diff --git a/drivers/cc110x/cc110x_settings.c b/drivers/cc110x/cc110x_settings.c index 3a561ec81c..47241bba75 100644 --- a/drivers/cc110x/cc110x_settings.c +++ b/drivers/cc110x/cc110x_settings.c @@ -84,7 +84,7 @@ const char cc110x_conf[CC110X_CONF_SIZE] = { * (e.g. a huge frame is dropped before it fully received) which reduces * the system's load. Thus, it is enabled. */ - 0x02, + CC110X_PKTCTRL1_VALUE | CC110X_PKTCTRL1_ADDR_MATCH, /* * PKTCTRL0; default: 0x45 * Data whitening enabled, use RX/TX FIFOs, CRC enabled, @@ -291,7 +291,7 @@ const char cc110x_conf[CC110X_CONF_SIZE] = { * Why not default: * Use a reasonable TX power level instead of the lowest. */ - 0x14, + 0x10 | CC110X_TX_POWER_0_DBM, /* * FSCAL3, FSCAL2, FSCAL1, FSCAL0; defaults: 0xA9, 0x0A, 0x20, 0x0d * These values store calibration date of the CC1100/CC1101 transceiver. diff --git a/drivers/cc110x/include/cc110x_constants.h b/drivers/cc110x/include/cc110x_constants.h index 0da337b465..45e5280183 100644 --- a/drivers/cc110x/include/cc110x_constants.h +++ b/drivers/cc110x/include/cc110x_constants.h @@ -206,6 +206,27 @@ extern "C" { */ #define CC110X_REG_IOCFG0 0x02 +/** + * @brief PKTCTRL1 configuration register + * + * This register contains multiple configuration settings. + * + * Layout: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * 7 6 5 4 3 2 1 0 + * +-+-+-+-+-+-+-+-+ + * | PQT |U|C|S|ADR| + * +-+-+-+-+-+-+-+-+ + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * - PQT (bits 7-5): Preabmle quality estimator threshold + * - U (bit 4): unused, always 0 + * - C (bit 3): Auto-clear RX FIFO on CRC mismatch (if frame fits in FIFO) + * - S (bit 2): Append status + * - ADR (bits 1-0): Address check setting + */ +#define CC110X_REG_PKTCTRL1 0x07 + /** * @brief Device address */ @@ -516,6 +537,39 @@ extern "C" { */ #define CC110X_FIFO_SIZE 64 +/** + * @brief Value of the bits 7-2 of the PKTCTRL1 configuration register used + * in this driver + */ +#define CC110X_PKTCTRL1_VALUE 0x00 + +/** + * @name Possible address matching policies + * + * See page 73 in the data sheet. The policy should be combined with + * @ref CC110X_PKTCTRL1_VALUE via bitwise or. (Only modes compatible with the + * driver are defined.) + * + * @{ + */ +/** + * @brief Accept incoming frames regardless of address + */ +#define CC110X_PKTCTRL1_ADDR_ALL 0x00 +/** + * @brief Accept frames with matching address or broadcast address + */ +#define CC110X_PKTCTRL1_ADDR_MATCH 0x02 +/** + * @brief Bitmask to access address matching mode of the CC110x from the + * PKTCTRL1 register + * + * Apply this using bitwise and to the value of the PKTCTRL1 register to get the + * address matching mode currently used. + */ +#define CC110X_PKTCTRL1_GET_ADDR_MODE 0x03 +/** @} */ + #ifdef __cplusplus } #endif diff --git a/drivers/include/cc110x.h b/drivers/include/cc110x.h index e19bc26c78..f1d77055fe 100644 --- a/drivers/include/cc110x.h +++ b/drivers/include/cc110x.h @@ -303,7 +303,7 @@ typedef enum { CC110X_TX_POWER_0_DBM, /**< 0 dBm */ CC110X_TX_POWER_PLUS_5_DBM, /**< 5 dBm */ CC110X_TX_POWER_PLUS_7_DBM, /**< 7 dBm */ - CC110X_TX_POWER_PLUS_10_DBM, /**< 1 dBm */ + CC110X_TX_POWER_PLUS_10_DBM, /**< 10 dBm */ CC110X_TX_POWER_NUMOF, /**< Number of TX power options */ } cc110x_tx_power_t;