diff --git a/drivers/include/ng_at86rf2xx.h b/drivers/include/ng_at86rf2xx.h index b62e5edfa..5b8b02c04 100644 --- a/drivers/include/ng_at86rf2xx.h +++ b/drivers/include/ng_at86rf2xx.h @@ -67,6 +67,18 @@ extern "C" { #endif /** @} */ +/** + * @brief Frequency configuration + * @{ + */ +#ifdef MODULE_NG_AT86RF212B +typedef enum { + NG_AT86RF2XX_FREQ_915MHZ, /**< frequency 915MHz enabled */ + NG_AT86RF2XX_FREQ_868MHZ, /**< frequency 868MHz enabled */ +} ng_at86rf2xx_freq_t; +#endif +/** @} */ + /** * @brief Default PAN ID * @@ -137,6 +149,10 @@ typedef struct { uint8_t seq_nr; /**< sequence number to use next */ uint8_t frame_len; /**< length of the current TX frame */ uint16_t pan; /**< currently used PAN ID */ + uint8_t chan; /**< currently used channel */ +#ifdef MODULE_NG_AT86RF212B + ng_at86rf2xx_freq_t freq; /**< currently used frequency */ +#endif uint8_t addr_short[2]; /**< the radio's short address */ uint8_t addr_long[8]; /**< the radio's long address */ uint16_t options; /**< state of used options */ @@ -230,6 +246,25 @@ uint8_t ng_at86rf2xx_get_chan(ng_at86rf2xx_t *dev); */ void ng_at86rf2xx_set_chan(ng_at86rf2xx_t *dev, uint8_t chan); +#ifdef MODULE_NG_AT86RF212B +/** + * @brief Get the configured frequency of the given device + * + * @param[in] dev device to read from + * + * @return the currently set frequency + */ +ng_at86rf2xx_freq_t ng_at86rf2xx_get_freq(ng_at86rf2xx_t *dev); + +/** + * @brief Set the frequency of the given device + * + * @param[in] dev device to write to + * @param[in] chan frequency to set + */ +void ng_at86rf2xx_set_freq(ng_at86rf2xx_t *dev, ng_at86rf2xx_freq_t freq); +#endif + /** * @brief Get the configured PAN ID of the given device * diff --git a/drivers/ng_at86rf2xx/include/ng_at86rf2xx_registers.h b/drivers/ng_at86rf2xx/include/ng_at86rf2xx_registers.h index 35c7429ce..6616956de 100644 --- a/drivers/ng_at86rf2xx/include/ng_at86rf2xx_registers.h +++ b/drivers/ng_at86rf2xx/include/ng_at86rf2xx_registers.h @@ -87,6 +87,9 @@ extern "C" { #define NG_AT86RF2XX_REG__XOSC_CTRL (0x12) #define NG_AT86RF2XX_REG__CC_CTRL_1 (0x14) #define NG_AT86RF2XX_REG__RX_SYN (0x15) +#ifdef MODULE_NG_AT86RF212B +#define NG_AT86RF2XX_REG__RF_CTRL_0 (0x16) +#endif #define NG_AT86RF2XX_REG__XAH_CTRL_1 (0x17) #define NG_AT86RF2XX_REG__FTN_CTRL (0x18) #define NG_AT86RF2XX_REG__PLL_CF (0x1A) @@ -152,13 +155,17 @@ extern "C" { /** @} */ /** - * @brief Bitfield definitions for the TXR_CTRL_2 register + * @brief Bitfield definitions for the TRX_CTRL_2 register * @{ */ #define NG_AT86RF2XX_TRX_CTRL_2_MASK__RX_SAFE_MODE (0x80) -#define NG_AT86RF2XX_TRX_CTRL_2_MASK__SUB_MODE (0x4) -#define NG_AT86RF2XX_TRX_CTRL_2_MASK__OQPSK_DATA_RATE (0x03) +#define NG_AT86RF2XX_TRX_CTRL_2_MASK__FREQ_MODE (0x3F) +#define NG_AT86RF2XX_TRX_CTRL_2_MASK__TRX_OFF_AVDD_EN (0x40) #define NG_AT86RF2XX_TRX_CTRL_2_MASK__OQPSK_SCRAM_EN (0x20) +#define NG_AT86RF2XX_TRX_CTRL_2_MASK__ALT_SPECTRUM (0x10) +#define NG_AT86RF2XX_TRX_CTRL_2_MASK__BPSK_OQPSK (0x08) +#define NG_AT86RF2XX_TRX_CTRL_2_MASK__SUB_MODE (0x04) +#define NG_AT86RF2XX_TRX_CTRL_2_MASK__OQPSK_DATA_RATE (0x03) /** @} */ /** @@ -238,9 +245,17 @@ extern "C" { * @brief Bitfield definitions for the PHY_TX_PWR register * @{ */ +#ifdef MODULE_NG_AT86RF212B +#define NG_AT86RF2XX_PHY_TX_PWR_MASK__PA_BOOST (0x80) +#define NG_AT86RF2XX_PHY_TX_PWR_MASK__GC_PA (0x60) +#define NG_AT86RF2XX_PHY_TX_PWR_MASK__TX_PWR (0x1F) +#elif MODULE_NG_AT86RF231 #define NG_AT86RF2XX_PHY_TX_PWR_MASK__PA_BUF_LT (0xC0) #define NG_AT86RF2XX_PHY_TX_PWR_MASK__PA_LT (0x30) #define NG_AT86RF2XX_PHY_TX_PWR_MASK__TX_PWR (0x0F) +#else +#define NG_AT86RF2XX_PHY_TX_PWR_MASK__TX_PWR (0x0F) +#endif #define NG_AT86RF2XX_PHY_TX_PWR_DEFAULT__PA_BUF_LT (0xC0) #define NG_AT86RF2XX_PHY_TX_PWR_DEFAULT__PA_LT (0x00) #define NG_AT86RF2XX_PHY_TX_PWR_DEFAULT__TX_PWR (0x00) @@ -311,6 +326,16 @@ extern "C" { #define NG_AT86RF2XX_CSMA_SEED_1__AACK_I_AM_COORD (0x08) /** @} */ +/** + * @brief Bitfield definitions for the RF_CTRL_0 register + * @{ + */ +#ifdef MODULE_NG_AT86RF212B +#define NG_AT86RF2XX_RF_CTRL_0_MASK__PA_LT (0xC0) +#define NG_AT86RF2XX_RF_CTRL_0_MASK__GC_TX_OFFS (0x03) +#endif +/** @} */ + #ifdef __cplusplus } #endif diff --git a/drivers/ng_at86rf2xx/ng_at86rf2xx.c b/drivers/ng_at86rf2xx/ng_at86rf2xx.c index 0995b15ff..145f4ef97 100644 --- a/drivers/ng_at86rf2xx/ng_at86rf2xx.c +++ b/drivers/ng_at86rf2xx/ng_at86rf2xx.c @@ -85,7 +85,6 @@ int ng_at86rf2xx_init(ng_at86rf2xx_t *dev, spi_t spi, spi_speed_t spi_speed, void ng_at86rf2xx_reset(ng_at86rf2xx_t *dev) { - uint8_t tmp; #if CPUID_ID_LEN uint8_t cpuid[CPUID_ID_LEN]; uint16_t addr_short; @@ -145,16 +144,14 @@ void ng_at86rf2xx_reset(ng_at86rf2xx_t *dev) dev->proto = NG_NETTYPE_UNDEF; #endif /* enable safe mode (protect RX FIFO until reading data starts) */ - tmp = NG_AT86RF2XX_TRX_CTRL_2_MASK__RX_SAFE_MODE; + ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__TRX_CTRL_2, + NG_AT86RF2XX_TRX_CTRL_2_MASK__RX_SAFE_MODE); #ifdef MODULE_NG_AT86RF212 - /* settings used by Linux 4.0rc at86rf212b driver */ - tmp |= (NG_AT86RF2XX_TRX_CTRL_2_MASK__SUB_MODE - | NG_AT86RF2XX_TRX_CTRL_2_MASK__OQPSK_SCRAM_EN); + ng_at86rf2xx_set_freq(NG_AT86RF2XX_FREQ_915MHZ); #endif - ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__TRX_CTRL_2, tmp); /* enable interrupts */ ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__IRQ_MASK, - NG_AT86RF2XX_IRQ_STATUS_MASK__TRX_END); + NG_AT86RF2XX_IRQ_STATUS_MASK__TRX_END); /* go into RX state */ ng_at86rf2xx_set_state(dev, NG_AT86RF2XX_STATE_RX_AACK_ON); diff --git a/drivers/ng_at86rf2xx/ng_at86rf2xx_getset.c b/drivers/ng_at86rf2xx/ng_at86rf2xx_getset.c index 5fc33807b..e89a1bcc7 100644 --- a/drivers/ng_at86rf2xx/ng_at86rf2xx_getset.c +++ b/drivers/ng_at86rf2xx/ng_at86rf2xx_getset.c @@ -15,6 +15,7 @@ * * @author Thomas Eichinger * @author Hauke Petersen + * @author Baptiste Clenet * * @} */ @@ -27,14 +28,51 @@ #define ENABLE_DEBUG (0) #include "debug.h" +#ifdef MODULE_NG_AT86RF212B +static const uint8_t dbm_to_tx_pow_868[] = {0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, + 0x17, 0x15, 0x14, 0x13, 0x12, 0x11, + 0x10, 0x0f, 0x31, 0x30, 0x2f, 0x94, + 0x93, 0x91, 0x90, 0x29, 0x49, 0x48, + 0x47, 0xad, 0xcd, 0xcc, 0xcb, 0xea, + 0xe9, 0xe8, 0xe7, 0xe6, 0xe4, 0x80, + 0xa0}; +static const uint8_t dbm_to_tx_pow_915[] = {0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x17, + 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, + 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, + 0x09, 0x91, 0x08, 0x07, 0x05, 0x27, + 0x04, 0x03, 0x02, 0x01, 0x00, 0x86, + 0x40, 0x84, 0x83, 0x82, 0x80, 0xc1, + 0xc0}; +int16_t tx_pow_to_dbm(ng_at86rf2xx_freq_t freq, uint8_t reg) { + for(int i = 0; i < 38; i++){ + if(freq == NG_AT86RF2XX_FREQ_868MHZ){ + if (dbm_to_tx_pow_868[i] == reg) { + return i -25; + } + } else if (freq == NG_AT86RF2XX_FREQ_915MHZ){ + if (dbm_to_tx_pow_915[i] == reg) { + return i -25; + } + } + } + return 0; +} +#elif MODULE_NG_AT86RF233 +static const int16_t tx_pow_to_dbm[] = {4, 4, 3, 3, 2, 2, 1, + 0, -1, -2, -3, -4, -6, -8, -12, -17}; +static const uint8_t dbm_to_tx_pow[] = {0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, + 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, + 0x0b, 0x0b, 0x0a, 0x09, 0x08, 0x07, + 0x06, 0x05, 0x03,0x00}; +#else static const int16_t tx_pow_to_dbm[] = {3, 3, 2, 2, 1, 1, 0, -1, -2, -3, -4, -5, -7, -9, -12, -17}; - static const uint8_t dbm_to_tx_pow[] = {0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x03, 0x00}; +#endif uint16_t ng_at86rf2xx_get_addr_short(ng_at86rf2xx_t *dev) { @@ -72,8 +110,7 @@ void ng_at86rf2xx_set_addr_long(ng_at86rf2xx_t *dev, uint64_t addr) uint8_t ng_at86rf2xx_get_chan(ng_at86rf2xx_t *dev) { - uint8_t res = ng_at86rf2xx_reg_read(dev, NG_AT86RF2XX_REG__PHY_CC_CCA); - return (res & NG_AT86RF2XX_PHY_CC_CCA_MASK__CHANNEL); + return dev->chan; } void ng_at86rf2xx_set_chan(ng_at86rf2xx_t *dev, uint8_t channel) @@ -84,12 +121,53 @@ void ng_at86rf2xx_set_chan(ng_at86rf2xx_t *dev, uint8_t channel) || channel > NG_AT86RF2XX_MAX_CHANNEL) { return; } + dev->chan = channel; tmp = ng_at86rf2xx_reg_read(dev, NG_AT86RF2XX_REG__PHY_CC_CCA); tmp &= ~(NG_AT86RF2XX_PHY_CC_CCA_MASK__CHANNEL); tmp |= (channel & NG_AT86RF2XX_PHY_CC_CCA_MASK__CHANNEL); ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__PHY_CC_CCA, tmp); } +#ifdef MODULE_NG_AT86RF212B +ng_at86rf2xx_freq_t ng_at86rf2xx_get_freq(ng_at86rf2xx_t *dev) +{ + return dev->freq; +} + +void ng_at86rf2xx_set_freq(ng_at86rf2xx_t *dev, ng_at86rf2xx_freq_t freq) +{ + uint8_t tmp1 = 0, tmp2 = 0; + tmp1 = ng_at86rf2xx_reg_read(dev, NG_AT86RF2XX_REG__TRX_CTRL_2); + tmp1 &= ~(NG_AT86RF2XX_TRX_CTRL_2_MASK__FREQ_MODE); + + if (freq == NG_AT86RF2XX_FREQ_915MHZ) { + dev->freq = NG_AT86RF2XX_FREQ_915MHZ; + /* settings used by Linux 4.0rc at86rf212b driver - BPSK-40*/ + tmp1 |= NG_AT86RF2XX_TRX_CTRL_2_MASK__SUB_MODE + | NG_AT86RF2XX_TRX_CTRL_2_MASK__OQPSK_SCRAM_EN; + tmp2 = 0x03; + + if (dev->chan == 0) { + ng_at86rf2xx_set_chan(dev,NG_AT86RF2XX_DEFAULT_CHANNEL); + } else { + ng_at86rf2xx_set_chan(dev,dev->chan); + } + } else if (freq == NG_AT86RF2XX_FREQ_868MHZ) { + dev->freq = NG_AT86RF2XX_FREQ_868MHZ; + /* OQPSK-SIN-RC-100 IEEE802.15.4 for 868,3MHz */ + tmp1 |= NG_AT86RF2XX_TRX_CTRL_2_MASK__BPSK_OQPSK; + tmp2 = 0x02; + + /* Channel = 0 for 868MHz means 868.3MHz, only one available */ + ng_at86rf2xx_set_chan(dev,0x00); + } else { + return; + } + ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__TRX_CTRL_2, tmp1); + ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__RF_CTRL_0, tmp2); +} +#endif + uint16_t ng_at86rf2xx_get_pan(ng_at86rf2xx_t *dev) { return dev->pan; @@ -105,21 +183,51 @@ void ng_at86rf2xx_set_pan(ng_at86rf2xx_t *dev, uint16_t pan) int16_t ng_at86rf2xx_get_txpower(ng_at86rf2xx_t *dev) { +#ifdef MODULE_NG_AT86RF212B + uint8_t txpower = ng_at86rf2xx_reg_read(dev, NG_AT86RF2XX_REG__PHY_TX_PWR); + printf("txpower value: %x\n", txpower); + return tx_pow_to_dbm(dev->freq, txpower); +#else uint8_t txpower = ng_at86rf2xx_reg_read(dev, NG_AT86RF2XX_REG__PHY_TX_PWR) & NG_AT86RF2XX_PHY_TX_PWR_MASK__TX_PWR; return tx_pow_to_dbm[txpower]; +#endif } void ng_at86rf2xx_set_txpower(ng_at86rf2xx_t *dev, int16_t txpower) { +#ifdef MODULE_NG_AT86RF212B + txpower += 25; +#else txpower += 17; +#endif if (txpower < 0) { txpower = 0; +#ifdef MODULE_NG_AT86RF212B + } else if (txpower > 36) { + txpower = 36; +#elif MODULE_NG_AT86RF233 + } else if (txpower > 21) { + txpower = 21; +#else } else if (txpower > 20) { txpower = 20; +#endif + } +#ifdef MODULE_NG_AT86RF212B + if (dev->freq == NG_AT86RF2XX_FREQ_915MHZ) { + ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__PHY_TX_PWR, + dbm_to_tx_pow_915[txpower]); + } else if (dev->freq == NG_AT86RF2XX_FREQ_868MHZ) { + ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__PHY_TX_PWR, + dbm_to_tx_pow_868[txpower]); + } else { + return; } +#else ng_at86rf2xx_reg_write(dev, NG_AT86RF2XX_REG__PHY_TX_PWR, dbm_to_tx_pow[txpower]); +#endif } void ng_at86rf2xx_set_option(ng_at86rf2xx_t *dev, uint16_t option, bool state)