Browse Source

drivers/kw2xrf: adapt for the netdev2 interface

Adapt the kw2xrf driver for the netdev2 interface.
This patch also adds overwrites.h, the header provides overwrite
values for the kw2xrf PHY.
patch-1
Johann Fischer 7 years ago committed by smlng
parent
commit
cf32ff7f19
  1. 5
      drivers/Makefile.dep
  2. 140
      drivers/include/kw2xrf.h
  3. 70
      drivers/kw2xrf/include/kw2xrf_getset.h
  4. 129
      drivers/kw2xrf/include/kw2xrf_intern.h
  5. 31
      drivers/kw2xrf/include/kw2xrf_netdev.h
  6. 216
      drivers/kw2xrf/include/kw2xrf_reg.h
  7. 50
      drivers/kw2xrf/include/kw2xrf_spi.h
  8. 47
      drivers/kw2xrf/include/kw2xrf_tm.h
  9. 308
      drivers/kw2xrf/include/overwrites.h
  10. 1311
      drivers/kw2xrf/kw2xrf.c
  11. 516
      drivers/kw2xrf/kw2xrf_getset.c
  12. 230
      drivers/kw2xrf/kw2xrf_intern.c
  13. 765
      drivers/kw2xrf/kw2xrf_netdev.c
  14. 112
      drivers/kw2xrf/kw2xrf_spi.c
  15. 181
      drivers/kw2xrf/kw2xrf_tm.c
  16. 24
      sys/auto_init/netif/auto_init_kw2xrf.c

5
drivers/Makefile.dep

@ -116,8 +116,11 @@ endif
ifneq (,$(filter kw2xrf,$(USEMODULE)))
USEMODULE += ieee802154
USEMODULE += netif
USEMODULE += netdev2_ieee802154
ifneq (,$(filter gnrc_netdev_default,$(USEMODULE)))
USEMODULE += gnrc_nomac
# XXX: this can be modelled as a dependency for gnrc_netdev_default as soon
# as all drivers are ported to netdev2
USEMODULE += gnrc_netdev2
endif
endif

140
drivers/include/kw2xrf.h

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 Phytec Messtechnik GmbH
* Copyright (C) 2016 Phytec Messtechnik GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -8,12 +8,12 @@
/**
* @defgroup drivers_kw2xrf kw2x radio-driver
* @ingroup drivers_netdev
* @brief Device driver for the Freescale KW2xD radio
* @ingroup drivers_netdev_netdev2
* @brief Device driver for the NXP CR20A and KW2xD radios
* @{
*
* @file
* @brief Interface definition for the KW2xD device driver
* @brief Interface definition for the kw2xrf driver
*
* @author Johann Fischer <j.fischer@phytec.de>
* @author Jonas Remmert <j.remmert@phytec.de>
@ -27,8 +27,9 @@
#include "board.h"
#include "periph/spi.h"
#include "periph/gpio.h"
#include "net/gnrc/netdev.h"
#include "net/ieee802154.h"
#include "net/netdev2.h"
#include "net/netdev2/ieee802154.h"
#include "net/gnrc/nettype.h"
#ifdef __cplusplus
extern "C" {
@ -39,24 +40,15 @@ extern "C" {
*/
#define KW2XRF_MAX_PKT_LENGTH (IEEE802154_FRAME_LEN_MAX)
/**
* @brief Default protocol for data that is coming in
*/
#ifdef MODULE_GNRC_SIXLOWPAN
#define KW2XRF_DEFAULT_PROTOCOL GNRC_NETTYPE_SIXLOWPAN
#else
#define KW2XRF_DEFAULT_PROTOCOL GNRC_NETTYPE_UNDEF
#endif
/**
* @brief Default short address used after initialization
*/
#define KW2XRF_DEFAULT_SHORT_ADDR (0x0002)
#define KW2XRF_DEFAULT_SHORT_ADDR (0x0042)
/**
* @brief Default short address used after initialization
*/
#define KW2XRF_DEFAULT_ADDR_LONG (0x0000000000000000)
#define KW2XRF_DEFAULT_ADDR_LONG (0x0000000DEADCAB1E)
/**
* @brief Default PAN ID used after initialization
@ -72,6 +64,8 @@ extern "C" {
#ifndef KW2XRF_DEFAULT_CHANNEL
#define KW2XRF_DEFAULT_CHANNEL (IEEE802154_DEFAULT_CHANNEL)
#endif
#define KW2XRF_MIN_CHANNEL (11U)
#define KW2XRF_MAX_CHANNEL (26U)
/**
* @brief Default TX_POWER in dbm used after initialization
@ -81,79 +75,99 @@ extern "C" {
/**
* @brief Maximum output power of the kw2x device in dBm
*/
#define MKW2XDRF_OUTPUT_POWER_MAX (8)
#define MKW2XDRF_OUTPUT_POWER_MAX (8)
/**
* @brief Minimum output power of the kw2x device in dBm
*/
#define MKW2XDRF_OUTPUT_POWER_MIN (-35)
#define MKW2XDRF_OUTPUT_POWER_MIN (-35)
/**
* @brief Internal device option flags
*
* `0x00ff` is reserved for general IEEE 802.15.4 flags
* (see @ref netdev2_ieee802154_t)
*
* @{
*/
#define KW2XRF_OPT_AUTOACK (0x0001) /**< auto ACKs active */
#define KW2XRF_OPT_CSMA (0x0002) /**< CSMA active */
#define KW2XRF_OPT_PROMISCUOUS (0x0004) /**< promiscuous mode active */
#define KW2XRF_OPT_PRELOADING (0x0008) /**< preloading enabled */
#define KW2XRF_OPT_TELL_TX_START (0x0010) /**< notify MAC layer on TX start */
#define KW2XRF_OPT_TELL_TX_END (0x0020) /**< notify MAC layer on TX finished */
#define KW2XRF_OPT_TELL_RX_START (0x0040) /**< notify MAC layer on RX start */
#define KW2XRF_OPT_TELL_RX_END (0x0080) /**< notify MAC layer on RX finished */
#define KW2XRF_OPT_RAWDUMP (0x0100) /**< pass RAW frame data to upper layer */
#define KW2XRF_OPT_SRC_ADDR_LONG (0x0200) /**< send data using long source address */
#define KW2XRF_OPT_USE_SRC_PAN (0x0400) /**< do not compress source PAN ID */
#define KW2XRF_OPT_SRC_ADDR_LONG (NETDEV2_IEEE802154_SRC_MODE_LONG) /**< legacy define */
#define KW2XRF_OPT_RAWDUMP (NETDEV2_IEEE802154_RAW) /**< legacy define */
#define KW2XRF_OPT_ACK_REQ (NETDEV2_IEEE802154_ACK_REQ) /**< legacy define */
#define KW2XRF_OPT_AUTOCCA (0x0100) /**< CCA befor TX active */
#define KW2XRF_OPT_PROMISCUOUS (0x0200) /**< promiscuous mode
* active */
#define KW2XRF_OPT_PRELOADING (0x0400) /**< preloading enabled */
#define KW2XRF_OPT_TELL_TX_START (0x0800) /**< notify MAC layer on TX
* start */
#define KW2XRF_OPT_TELL_TX_END (0x1000) /**< notify MAC layer on TX
* finished */
#define KW2XRF_OPT_TELL_RX_START (0x2000) /**< notify MAC layer on RX
* start */
#define KW2XRF_OPT_TELL_RX_END (0x4000) /**< notify MAC layer on RX
* finished */
#define KW2XRF_OPT_AUTOACK (0x8000) /**< enable automatically ACK
* for incommint packet */
/** @} */
/**
* @brief kw2xrf device descriptor
* @brief struct holding all params needed for device initialization
*/
typedef struct kw2xrf_params {
spi_t spi; /**< SPI bus the device is connected to */
spi_speed_t spi_speed; /**< SPI speed to use */
gpio_t cs_pin; /**< GPIO pin connected to chip select */
gpio_t int_pin; /**< GPIO pin connected to the interrupt pin */
} kw2xrf_params_t;
/**
* @brief Device descriptor for KW2XRF radio devices
*
* @extends netdev2_ieee802154_t
*/
typedef struct {
/* netdev fields */
gnrc_netdev_driver_t const *driver; /**< Pointer to the devices interface */
gnrc_netdev_event_cb_t event_cb; /**< Netdev event callback */
kernel_pid_t mac_pid; /**< The driver's thread's PID */
/* driver specific fields */
uint8_t buf[KW2XRF_MAX_PKT_LENGTH]; /**< Buffer for incoming or outgoing packets */
netopt_state_t state; /**< Variable to keep radio driver's state */
uint8_t seq_nr; /**< Next packets sequence number */
uint16_t radio_pan; /**< The PAN the radio device is using */
uint8_t radio_channel; /**< The channel the radio device is using */
uint8_t addr_short[2]; /**< The short address the radio device is using */
uint8_t addr_long[8]; /**< The long address the radio device is using */
uint16_t option; /**< Bit field to save enable/disable options */
int8_t tx_power; /**< The current tx-power setting of the device */
gnrc_nettype_t proto; /**< Protocol the interface speaks */
netdev2_ieee802154_t netdev; /**< netdev2 parent struct */
/**
* @brief device specific fields
* @{
*/
kw2xrf_params_t params; /**< parameters for initialization */
uint8_t buf[KW2XRF_MAX_PKT_LENGTH]; /**< Buffer for incoming or outgoing packets */
uint8_t state; /**< current state of the radio */
uint8_t tx_frame_len; /**< length of the current TX frame */
uint8_t idle_state; /**< state to return to after sending */
uint8_t pending_tx; /**< keep track of pending TX calls
this is required to know when to
return to @ref kw2xrf_t::idle_state */
int16_t tx_power; /**< The current tx-power setting of the device */
/** @} */
} kw2xrf_t;
/**
* @brief Setup an KW2XRF based device state
*
* @param[out] dev device descriptor
* @param[in] params parameters for device initialization
*/
void kw2xrf_setup(kw2xrf_t *dev, const kw2xrf_params_t *params);
/**
* @brief Initialize the given KW2XRF device
* @param[out] dev device descriptor
* @param[in] spi SPI bus the device is connected to
* @param[in] spi_clk SPI bus clock speed to use
* @param[in] cs_pin GPIO pin connected to chip select
* @param[in] int_pin GPIO pin connected to the interrupt pin
* @param[in] cb irq callback
*
* @return 0 on success
* @return <0 on error
*/
int kw2xrf_init(kw2xrf_t *dev, spi_t spi, spi_clk_t spi_clk,
gpio_t cs_pin, gpio_t int_pin);
int kw2xrf_init(kw2xrf_t *dev, gpio_cb_t cb);
/**
* @brief struct holding all params needed for device initialization
* @brief Configure radio with default values
*
* @param[in] dev device to reset
*/
typedef struct kw2xrf_params {
spi_t spi; /**< SPI bus the device is connected to */
spi_clk_t spi_speed; /**< SPI speed to use */
gpio_t cs_pin; /**< GPIO pin connected to chip select */
gpio_t int_pin; /**< GPIO pin connected to the interrupt pin */
} kw2xrf_params_t;
void kw2xrf_reset_phy(kw2xrf_t *dev);
/**
* @brief Reference to the KW2XRF driver interface
*/
extern const gnrc_netdev_driver_t kw2xrf_driver;
#ifdef __cplusplus
}

70
drivers/kw2xrf/include/kw2xrf_getset.h

@ -0,0 +1,70 @@
/*
* Copyright (C) 2016 Phytec Messtechnik GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup
* @{
*
* @file
* @brief get/set interfaces for kw2xrf driver
*
* @author Johann Fischer <j.fischer@phytec.de>
*/
#include "kw2xrf.h"
#ifdef __cplusplus
extern "C" {
#endif
void kw2xrf_set_tx_power(kw2xrf_t *dev, int16_t txpower);
uint16_t kw2xrf_get_txpower(kw2xrf_t *dev);
uint8_t kw2xrf_get_channel(kw2xrf_t *dev);
int kw2xrf_set_channel(kw2xrf_t *dev, uint8_t val);
void kw2xrf_abort_sequence(kw2xrf_t *dev);
void kw2xrf_set_idle_sequence(kw2xrf_t *dev);
void kw2xrf_set_sequence(kw2xrf_t *dev, kw2xrf_physeq_t seq);
void kw2xrf_set_pan(kw2xrf_t *dev, uint16_t pan);
void kw2xrf_set_addr_short(kw2xrf_t *dev, uint16_t addr);
void kw2xrf_set_addr_long(kw2xrf_t *dev, uint64_t addr);
uint16_t kw2xrf_get_addr_short(kw2xrf_t *dev);
uint64_t kw2xrf_get_addr_long(kw2xrf_t *dev);
int8_t kw2xrf_get_cca_threshold(kw2xrf_t *dev);
void kw2xrf_set_cca_threshold(kw2xrf_t *dev, int8_t value);
void kw2xrf_set_cca_mode(kw2xrf_t *dev, uint8_t mode);
uint8_t kw2xrf_get_cca_mode(kw2xrf_t *dev);
uint32_t kw2xrf_get_rssi(uint32_t value);
netopt_state_t kw2xrf_get_status(kw2xrf_t *dev);
int kw2xrf_cca(kw2xrf_t *dev);
void kw2xrf_set_rx_watermark(kw2xrf_t *dev, uint8_t value);
void kw2xrf_set_option(kw2xrf_t *dev, uint16_t option, bool state);
#ifdef __cplusplus
}
#endif
/** @} */

129
drivers/kw2xrf/include/kw2xrf_intern.h

@ -0,0 +1,129 @@
/*
* Copyright (C) 2016 Phytec Messtechnik GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup
* @{
*
* @file
* @brief Internal function interfaces for kw2xrf driver
*
* @author Johann Fischer <j.fischer@phytec.de>
*/
#include <stdint.h>
#include "kw2xrf.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Power Modes */
typedef enum {
KW2XRF_HIBERNATE = 0,
KW2XRF_DOZE,
KW2XRF_IDLE,
KW2XRF_AUTODOZE,
} kw2xrf_powermode_t;
inline void kw2xrf_set_dreg_bit(kw2xrf_t *dev, uint8_t reg, uint8_t bit)
{
uint8_t tmp = kw2xrf_read_dreg(dev, reg);
tmp |= bit;
kw2xrf_write_dreg(dev, reg, tmp);
}
inline void kw2xrf_clear_dreg_bit(kw2xrf_t *dev, uint8_t reg, uint8_t bit)
{
uint8_t tmp = kw2xrf_read_dreg(dev, reg);
tmp &= ~bit;
kw2xrf_write_dreg(dev, reg, tmp);
}
/** Enable any transceiver interrupt to assert IRQ_B */
inline void kw2xrf_enable_irq_b(kw2xrf_t *dev)
{
kw2xrf_clear_dreg_bit(dev, MKW2XDM_PHY_CTRL4, MKW2XDM_PHY_CTRL4_TRCV_MSK);
}
/** Mask all transceiver interrupts to assert IRQ_B */
inline void kw2xrf_mask_irq_b(kw2xrf_t *dev)
{
kw2xrf_set_dreg_bit(dev, MKW2XDM_PHY_CTRL4, MKW2XDM_PHY_CTRL4_TRCV_MSK);
}
void kw2xrf_disable_interrupts(kw2xrf_t *dev);
void kw2xrf_update_overwrites(kw2xrf_t *dev);
void kw2xrf_set_out_clk(kw2xrf_t *dev);
void kw2xrf_set_power_mode(kw2xrf_t *dev, kw2xrf_powermode_t pm);
int kw2xrf_can_switch_to_idle(kw2xrf_t *dev);
typedef enum kw2xrf_timer_timebase {
KW2XRF_TIMEBASE_500000HZ = 2,
KW2XRF_TIMEBASE_250000HZ,
KW2XRF_TIMEBASE_125000HZ,
KW2XRF_TIMEBASE_62500HZ,
KW2XRF_TIMEBASE_31250HZ,
KW2XRF_TIMEBASE_15625HZ,
} kw2xrf_timer_timebase_t;
/**
* Initialize the Event Timer Block (up counter)
* The Event Timer Block provides:
* - Abort an RX and CCA sequence at pre-determined time
* - Latches "timestamp" value during packet reception
* - Initiates timer-triggered sequences
*/
void kw2xrf_timer_init(kw2xrf_t *dev, kw2xrf_timer_timebase_t tb);
void kw2xrf_timer2_seq_start_on(kw2xrf_t *dev);
void kw2xrf_timer2_seq_start_off(kw2xrf_t *dev);
void kw2xrf_timer3_seq_abort_on(kw2xrf_t *dev);
void kw2xrf_timer3_seq_abort_off(kw2xrf_t *dev);
/**
* Use T2CMP or T2PRIMECMP to Trigger Transceiver Operations
*/
void kw2xrf_trigger_tx_ops_enable(kw2xrf_t *dev, uint32_t timeout);
/**
* Disable Trigger for Transceiver Operations
*
*/
void kw2xrf_trigger_tx_ops_disable(kw2xrf_t *dev);
/**
* Use T3CMP to Abort an RX operation
*/
void kw2xrf_abort_rx_ops_enable(kw2xrf_t *dev, uint32_t timeout);
/**
* Disable Trigger to Abort an RX operation
*/
void kw2xrf_abort_rx_ops_disable(kw2xrf_t *dev);
void kw2xrf_seq_timeout_on(kw2xrf_t *dev, uint32_t timeout);
void kw2xrf_seq_timeout_off(kw2xrf_t *dev);
/**
* Returns Timestamp of the actual received packet
*/
uint32_t kw2xrf_get_timestamp(kw2xrf_t *dev);
#ifdef __cplusplus
}
#endif
/** @} */

31
drivers/kw2xrf/include/kw2xrf_netdev.h

@ -0,0 +1,31 @@
/*
* Copyright (C) 2016 Phytec Messtechnik GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup
* @{
*
* @file
* @brief Netdev interface for kw2xrf driver
*
* @author Johann Fischer <j.fischer@phytec.de>
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Reference to the netdev device driver struct
*/
extern const netdev2_driver_t kw2xrf_driver;
#ifdef __cplusplus
}
#endif
/** @} */

216
drivers/kw2xrf/include/kw2xrf_reg.h

@ -1,9 +1,43 @@
/*
* Copyright (C) 2015 Phytec Messtechnik GmbH
* Copyright (C) 2016 Phytec Messtechnik GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* The description of the registers was extracted from the
* Reference Manual MKW2xDxxxRM.pdf. After the release of MCR20A Device,
* it was extended by the undocumented registers from the file MCR20reg.h.
*
* Portions of this file are derived from material that is
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
@ -92,6 +126,24 @@ enum mkw2xdrf_dregister {
MKW2XDM_SEQ_STATE = 0x24, /**< Sequence Manager State */
MKW2XDM_LQI_VALUE = 0x25, /**< Link Quality Indicator */
MKW2XDM_RSSI_CCA_CNT = 0x26, /**< RSSI CCA CNT */
MKW2XDM_ASM_CTRL1 = 0x28,
MKW2XDM_ASM_CTRL2 = 0x29,
MKW2XDM_ASM_DATA_0 = 0x2A,
MKW2XDM_ASM_DATA_1 = 0x2B,
MKW2XDM_ASM_DATA_2 = 0x2C,
MKW2XDM_ASM_DATA_3 = 0x2D,
MKW2XDM_ASM_DATA_4 = 0x2E,
MKW2XDM_ASM_DATA_5 = 0x2F,
MKW2XDM_ASM_DATA_6 = 0x30,
MKW2XDM_ASM_DATA_7 = 0x31,
MKW2XDM_ASM_DATA_8 = 0x32,
MKW2XDM_ASM_DATA_9 = 0x33,
MKW2XDM_ASM_DATA_A = 0x34,
MKW2XDM_ASM_DATA_B = 0x35,
MKW2XDM_ASM_DATA_C = 0x36,
MKW2XDM_ASM_DATA_D = 0x37,
MKW2XDM_ASM_DATA_E = 0x38,
MKW2XDM_ASM_DATA_F = 0x39,
MKW2XDM_OVERWRITE_VER = 0x3b, /**< Overwrite Version Number */
MKW2XDM_CLK_OUT_CTRL = 0x3c, /**< CLK_OUT Control */
MKW2XDM_PWR_MODES = 0x3d, /**< Power Modes */
@ -124,13 +176,16 @@ enum mkw2xdrf_dregister {
#define MKW2XDM_IRQSTS3_TMR3IRQ (1 << 2)
#define MKW2XDM_IRQSTS3_TMR2IRQ (1 << 1)
#define MKW2XDM_IRQSTS3_TMR1IRQ (1 << 0)
#define MKW2XDM_IRQSTS3_TMR_IRQ_MASK 0xfu
#define MKW2XDM_IRQSTS3_TMR_IRQ_SHIFT 0x0u
#define MKW2XDM_IRQSTS3_TMR_IRQ(x) (((uint8_t)(((uint8_t)(x))<<MKW2XDM_IRQSTS3_TMR_IRQ_SHIFT))&MKW2XDM_IRQSTS3_TMR_IRQ_MASK)
#define MKW2XDM_PHY_CTRL1_TMRTRIGEN (1 << 7)
#define MKW2XDM_PHY_CTRL1_SLOTTED (1 << 6)
#define MKW2XDM_PHY_CTRL1_CCABFRTX (1 << 5)
#define MKW2XDM_PHY_CTRL1_RXACKRQD (1 << 4)
#define MKW2XDM_PHY_CTRL1_AUTOACK (1 << 3)
#define MKW2XDM_PHY_CTRL1_XCVSEQ_MASK 0x03u
#define MKW2XDM_PHY_CTRL1_XCVSEQ_MASK 0x07u
#define MKW2XDM_PHY_CTRL1_XCVSEQ(x) (((uint8_t)(((uint8_t)(x))<<0))&MKW2XDM_PHY_CTRL1_XCVSEQ_MASK)
#define MKW2XDM_PHY_CTRL2_CRC_MSK (1 << 7)
@ -227,6 +282,7 @@ enum mkw2xdrf_iregister {
MKW2XDMI_CCA_CTRL = 0x25, /**< CCA Control */
MKW2XDMI_CCA2_CORR_PEAKS = 0x26, /**< Clear Channel Assessment 2 Threshold Peak Compare */
MKW2XDMI_CCA2_THRESH = 0x27, /**< Clear Channel Assessment 2 Threshold */
MKW2XDMI_TMR_PRESCALE = 0x28, /**< Event Timer Time Base */
MKW2XDMI_GPIO_DATA = 0x2a, /**< GPIO Data */
MKW2XDMI_GPIO_DIR = 0x2b, /**< GPIO Direction Control */
MKW2XDMI_GPIO_PUL_EN = 0x2c, /**< GPIO Pullup Enable */
@ -234,8 +290,110 @@ enum mkw2xdrf_iregister {
MKW2XDMI_GPIO_DS = 0x2e, /**< GPIO Drive Strength */
MKW2XDMI_ANT_PAD_CTRL = 0x30, /**< Antenna Control */
MKW2XDMI_MISC_PAD_CTRL = 0x31, /**< Miscellaneous Pad Control */
MKW2XDMI_BSM_CTRL = 0x32,
MKW2XDMI__RNG = 0x34,
MKW2XDMI_RX_BYTE_COUNT = 0x35,
MKW2XDMI_RX_WTR_MARK = 0x36,
MKW2XDMI_SOFT_RESET = 0x37,
MKW2XDMI_TXDELAY = 0x38,
MKW2XDMI_ACKDELAY = 0x39,
MKW2XDMI_SEQ_MGR_CTRL = 0x3A,
MKW2XDMI_SEQ_MGR_STS = 0x3B,
MKW2XDMI_SEQ_T_STS = 0x3C,
MKW2XDMI_ABORT_STS = 0x3D,
MKW2XDMI_CCCA_BUSY_CNT = 0x3E,
MKW2XDMI_SRC_ADDR_CHECKSUM1 = 0x3F,
MKW2XDMI_SRC_ADDR_CHECKSUM2 = 0x40,
MKW2XDMI_SRC_TBL_VALID1 = 0x41,
MKW2XDMI_SRC_TBL_VALID2 = 0x42,
MKW2XDMI_FILTERFAIL_CODE1 = 0x43,
MKW2XDMI_FILTERFAIL_CODE2 = 0x44,
MKW2XDMI_SLOT_PRELOAD = 0x45,
MKW2XDMI_CORR_VT = 0x47,
MKW2XDMI_SYNC_CTRL = 0x48,
MKW2XDMI_PN_LSB_0 = 0x49,
MKW2XDMI_PN_LSB_1 = 0x4A,
MKW2XDMI_PN_MSB_0 = 0x4B,
MKW2XDMI_PN_MSB_1 = 0x4C,
MKW2XDMI_CORR_NVAL = 0x4D,
MKW2XDMI_TX_MODE_CTRL = 0x4E,
MKW2XDMI_SNF_THR = 0x4F,
MKW2XDMI_FAD_THR = 0x50,
MKW2XDMI_ANT_AGC_CTRL = 0x51, /**< Antenna AGC and FAD Control */
MKW2XDMI_AGC_THR1 = 0x52,
MKW2XDMI_AGC_THR2 = 0x53,
MKW2XDMI_AGC_HYS = 0x54,
MKW2XDMI_AFC = 0x55,
MKW2XDMI_LPPS_CTRL = 0x56, /**< LPPS_CTRL */
MKW2XDMI_PHY_STS = 0x58,
MKW2XDMI_RX_MAX_CORR = 0x59,
MKW2XDMI_RX_MAX_PREAMBLE = 0x5A,
MKW2XDMI_RSSI = 0x5B,
MKW2XDMI_PLL_DIG_CTRL = 0x5E,
MKW2XDMI_VCO_CAL = 0x5F,
MKW2XDMI_VCO_BEST_DIFF = 0x60,
MKW2XDMI_VCO_BIAS = 0x61,
MKW2XDMI_KMOD_CTRL = 0x62,
MKW2XDMI_KMOD_CAL = 0x63,
MKW2XDMI_PA_CAL = 0x64,
MKW2XDMI_PA_PWRCAL = 0x65,
MKW2XDMI_ATT_RSSI1 = 0x66,
MKW2XDMI_ATT_RSSI2 = 0x67,
MKW2XDMI_RSSI_OFFSET = 0x68,
MKW2XDMI_RSSI_SLOPE = 0x69,
MKW2XDMI_RSSI_CAL1 = 0x6A,
MKW2XDMI_RSSI_CAL2 = 0x6B,
MKW2XDMI_XTAL_CTRL = 0x6E,
MKW2XDMI_XTAL_COMP_MIN = 0x6F,
MKW2XDMI_XTAL_COMP_MAX = 0x70,
MKW2XDMI_XTAL_GM = 0x71,
MKW2XDMI_LNA_TUNE = 0x74,
MKW2XDMI_LNA_AGCGAIN = 0x75,
MKW2XDMI_CHF_PMA_GAIN = 0x78,
MKW2XDMI_CHF_IBUF = 0x79,
MKW2XDMI_CHF_QBUF = 0x7A,
MKW2XDMI_CHF_IRIN = 0x7B,
MKW2XDMI_CHF_QRIN = 0x7C,
MKW2XDMI_CHF_IL = 0x7D,
MKW2XDMI_CHF_QL = 0x7E,
MKW2XDMI_CHF_CC1 = 0x7F,
MKW2XDMI_CHF_CCL = 0x80,
MKW2XDMI_CHF_CC2 = 0x81,
MKW2XDMI_CHF_IROUT = 0x82,
MKW2XDMI_CHF_QROUT = 0x83,
MKW2XDMI_RSSI_CTRL = 0x86,
MKW2XDMI_PA_BIAS = 0x89,
MKW2XDMI_PA_TUNING = 0x8A,
MKW2XDMI_PMC_HP_TRIM = 0x8D,
MKW2XDMI_VREGA_TRIM = 0x8E,
MKW2XDMI_VCO_CTRL1 = 0x91,
MKW2XDMI_VCO_CTRL2 = 0x92,
MKW2XDMI_ANA_SPARE_OUT1 = 0x95,
MKW2XDMI_ANA_SPARE_OUT2 = 0x96,
MKW2XDMI_ANA_SPARE_IN = 0x97,
MKW2XDMI_MISCELLANEOUS = 0x98,
MKW2XDMI_SEQ_MGR_OVRD0 = 0x9A,
MKW2XDMI_SEQ_MGR_OVRD1 = 0x9B,
MKW2XDMI_SEQ_MGR_OVRD2 = 0x9C,
MKW2XDMI_SEQ_MGR_OVRD3 = 0x9D,
MKW2XDMI_SEQ_MGR_OVRD4 = 0x9E,
MKW2XDMI_SEQ_MGR_OVRD5 = 0x9F,
MKW2XDMI_SEQ_MGR_OVRD6 = 0xA0,
MKW2XDMI_SEQ_MGR_OVRD7 = 0xA1,
MKW2XDMI_TESTMODE_CTRL = 0xA3,
MKW2XDMI_DTM_CTRL1= 0xA4,
MKW2XDMI_DTM_CTRL2= 0xA5,
MKW2XDMI_ATM_CTRL1= 0xA6,
MKW2XDMI_ATM_CTRL2= 0xA7,
MKW2XDMI_ATM_CTRL3= 0xA8,
MKW2XDMI_LIM_FE_TEST_CTRL = 0xAA,
MKW2XDMI_CHF_TEST_CTRL = 0xAB,
MKW2XDMI_VCO_TEST_CTRL = 0xAC,
MKW2XDMI_PLL_TEST_CTRL = 0xAD,
MKW2XDMI_PA_TEST_CTRL = 0xAE,
MKW2XDMI_PMC_TEST_CTRL = 0xAF,
MKW2XDMI_SCAN_DTM_PROTECT_1 = 0xFE,
MKW2XDMI_SCAN_DTM_PROTECT_0 = 0xFF,
};
#define MKW2XDMI_PART_ID_MANUF_ID_MASK 0x60u
@ -279,6 +437,10 @@ enum mkw2xdrf_iregister {
#define MKW2XDMI_CCA2_CORR_PEAKS_CCA2_MIN_NUM_CORR_TH(x) (((uint8_t)(((uint8_t)(x))<<MKW2XDMI_CCA2_CORR_PEAKS_CCA2_MIN_NUM_CORR_TH_SHIFT))&MKW2XDMI_CCA2_CORR_PEAKS_CCA2_MIN_NUM_CORR_TH_MASK)
#define MKW2XDMI_CCA2_CORR_PEAKS_CCA2_NUM_CORR_PEAKS_MASK 0x0Fu
#define MKW2XDMI_TMR_PRESCALE_MASK 0x7u
#define MKW2XDMI_TMR_PRESCALE_SHIFT 0x0u
#define MKW2XDMI_TMR_PRESCALE_SET(x) (((uint8_t)(((uint8_t)(x))<<MKW2XDMI_TMR_PRESCALE_SHIFT))&MKW2XDMI_TMR_PRESCALE_MASK)
#define MKW2XDMI_GPIO_DATA8 (1 << 7)
#define MKW2XDMI_GPIO_DATA7 (1 << 6)
#define MKW2XDMI_GPIO_DATA6 (1 << 5)
@ -348,6 +510,56 @@ enum mkw2xdrf_iregister {
#define MKW2XDMI_LPPS_CTRL_LPPS_EN (1 << 0)
#define MKW2XDMI_SOFT_RESET_SOG_RST (1 << 7)
#define MKW2XDMI_SOFT_RESET_REGS_RST (1 << 4)
#define MKW2XDMI_SOFT_RESET_PLL_RST (1 << 3)
#define MKW2XDMI_SOFT_RESET_TX_RST (1 << 2)
#define MKW2XDMI_SOFT_RESET_RX_RST (1 << 1)
#define MKW2XDMI_SOFT_RESET_SEQ_MGR_RST (1 << 0)
#define MKW2XDMI_SEQ_MGR_CTRL_SEQ_STATE_CTRL_MASK 0x3
#define MKW2XDMI_SEQ_MGR_CTRL_SEQ_STATE_CTRL_SHIFT 6
#define MKW2XDMI_SEQ_MGR_CTRL_NO_RX_RECYCLE (1 << 5)
#define MKW2XDMI_SEQ_MGR_CTRL_LATCH_PREAMBLE (1 << 4)
#define MKW2XDMI_SEQ_MGR_CTRL_EVENT_TMR_DO_NOT_LATCH (1 << 3)
#define MKW2XDMI_SEQ_MGR_CTRL_CLR_NEW_SEQ_INHIBIT (1 << 2)
#define MKW2XDMI_SEQ_MGR_CTRL_PSM_LOCK_DIS (1 << 1)
#define MKW2XDMI_SEQ_MGR_CTRL_PLL_ABORT_OVRD (1 << 0)
#define MKW2XDMI_SEQ_MGR_STS_TMR2_SEQ_TRIG_ARMED (1 << 7)
#define MKW2XDMI_SEQ_MGR_STS_RX_MODE (1 << 6)
#define MKW2XDMI_SEQ_MGR_STS_RX_TIMEOUT_PENDING (1 << 5)
#define MKW2XDMI_SEQ_MGR_STS_NEW_SEQ_INHIBIT (1 << 4)
#define MKW2XDMI_SEQ_MGR_STS_SEQ_IDLE (1 << 3)
#define MKW2XDMI_SEQ_MGR_STS_XCVSEQ_ACTUAL_MASK 7
#define MKW2XDMI_ABORT_STS_PLL_ABORTED (1 << 2)
#define MKW2XDMI_ABORT_STS_TC3_ABORTED (1 << 1)
#define MKW2XDMI_ABORT_STS_SW_ABORTED (1 << 0)
#define MKW2XDMI_TESTMODE_CTRL_HOT_ANT (1 << 4)
#define MKW2XDMI_TESTMODE_CTRL_IDEAL_RSSI_EN (1 << 3)
#define MKW2XDMI_TESTMODE_CTRL_IDEAL_PFC_EN (1 << 2)
#define MKW2XDMI_TESTMODE_CTRL_CONTINUOUS_EN (1 << 1)
#define MKW2XDMI_TESTMODE_CTRL_FPGA_EN (1 << 0)
#define MKW2XDMI_DTM_CTRL1_ATM_LOCKED (1 << 7)
#define MKW2XDMI_DTM_CTRL1_DTM_EN (1 << 6)
#define MKW2XDMI_DTM_CTRL1_PAGE5 (1 << 5)
#define MKW2XDMI_DTM_CTRL1_PAGE4 (1 << 4)
#define MKW2XDMI_DTM_CTRL1_PAGE3 (1 << 3)
#define MKW2XDMI_DTM_CTRL1_PAGE2 (1 << 2)
#define MKW2XDMI_DTM_CTRL1_PAGE1 (1 << 1)
#define MKW2XDMI_DTM_CTRL1_PAGE0 (1 << 0)
#define MKW2XDMI_TX_MODE_CTRL_TX_INV (1 << 4)
#define MKW2XDMI_TX_MODE_CTRL_BT_EN (1 << 3)
#define MKW2XDMI_TX_MODE_CTRL_DTS2 (1 << 2)
#define MKW2XDMI_TX_MODE_CTRL_DTS1 (1 << 1)
#define MKW2XDMI_TX_MODE_CTRL_DTS0 (1 << 0)
#define MKW2XDMI_TX_MODE_CTRL_DTS_MASK 7
#ifdef __cplusplus
}
#endif

50
drivers/kw2xrf/include/kw2xrf_spi.h

@ -29,85 +29,111 @@ extern "C" {
/**
* @brief SPI interface initialization
* @param[in] spi SPI bus the device is connected to
* @param[in] spi_clk SPI clock speed to use
* @param[in] cs_pin GPIO pin connected to chip select
* @param[in] dev device descriptor
*
* @return 0 on success
* @return -1 on error
*/
int kw2xrf_spi_init(spi_t spi, spi_clk_t spi_clk, spi_cs_t cs_pin);
int kw2xrf_spi_init(kw2xrf_t *dev);
/**
* @brief Writes a byte to the kw2xrf register.
*
* @param[in] dev device descriptor
* @param[in] addr Address of the register to write.
* @param[in] value The value to write in the register.
*/
void kw2xrf_write_dreg(uint8_t addr, uint8_t value);
void kw2xrf_write_dreg(kw2xrf_t *dev, uint8_t addr, uint8_t value);
/**
* @brief Reads a byte from the kw2xrf register.
*
* @param[in] dev device descriptor
* @param[in] addr Address of the register to read.
* @return Value of the register.
*/
uint8_t kw2xrf_read_dreg(uint8_t addr);
uint8_t kw2xrf_read_dreg(kw2xrf_t *dev, uint8_t addr);
/**
* @brief Writes to kw2xrf direct registers.
*
* @param[in] dev device descriptor
* @param[in] addr Address of the register to write into.
* @param[in] buf Value that shall be written.
* @param[in] length Length of the register.
*/
size_t kw2xrf_write_dregs(kw2xrf_t *dev, uint8_t addr, uint8_t *buf, uint8_t length);
/**
* @brief Reads a byte from the kw2xrf indirect register.
*
* @param[in] dev device descriptor
* @param[in] addr Address of the register to read.
* @param[in] buf Buffer, where the content of the reg shall be written to.
* @param[in] length Length of the register.
*/
size_t kw2xrf_read_dregs(kw2xrf_t *dev, uint8_t addr, uint8_t *buf, uint8_t length);
/**
* @brief Writes to a byte from the kw2xrf indirect register.
*
* @param[in] dev device descriptor
* @param[in] addr Address of the register to write into.
* @param[in] value Value that shall be written.
*/
void kw2xrf_write_ireg(uint8_t addr, uint8_t value);
void kw2xrf_write_ireg(kw2xrf_t *dev, uint8_t addr, uint8_t value);
/**
* @brief Reads a byte from the kw2xrf indirect register.
*
* @param[in] dev device descriptor
* @param[in] addr Address of the register to read.
*
* @return value in the register
*/
uint8_t kw2xrf_read_ireg(uint8_t addr);
uint8_t kw2xrf_read_ireg(kw2xrf_t *dev, uint8_t addr);
/**
* @brief Writes to kw2xrf indirect registers.
*
* @param[in] dev device descriptor
* @param[in] addr Address of the register to write into.
* @param[in] buf Value that shall be written.
* @param[in] length Length of the register.
*/
void kw2xrf_write_iregs(uint8_t addr, uint8_t *buf, uint8_t length);
void kw2xrf_write_iregs(kw2xrf_t *dev, uint8_t addr, uint8_t *buf, uint8_t length);
/**
* @brief Reads a byte from the kw2xrf indirect register.
*
* @param[in] dev device descriptor
* @param[in] addr Address of the register to read.
* @param[in] buf Buffer, where the content of the reg shall be written to.
* @param[in] length Length of the register.
*/
void kw2xrf_read_iregs(uint8_t addr, uint8_t *buf, uint8_t length);
void kw2xrf_read_iregs(kw2xrf_t *dev, uint8_t addr, uint8_t *buf, uint8_t length);
/**
* @brief Writes multiple bytes to the kw2xrf fifo.
*
* @param[in] dev device descriptor
* @param[in] data A buffer with the value to write to the fifo.
* @param[in] data_length The count of bytes which should be written.
*
* @return number of bytes written.
*/
void kw2xrf_write_fifo(uint8_t *data, uint8_t data_length);
void kw2xrf_write_fifo(kw2xrf_t *dev, uint8_t *data, uint8_t data_length);
/**
* @brief Reads multiple bytes from the kw2xrf fifo.
*
* @param[in] dev device descriptor
* @param[out] data A buffer to store the value of the fifo.
* @param[in] data_length The count of bytes which should be read.
*
* @return number of bytes read.
*/
void kw2xrf_read_fifo(uint8_t *data, uint8_t data_length);
void kw2xrf_read_fifo(kw2xrf_t *dev, uint8_t *data, uint8_t data_length);
#ifdef __cplusplus
}

47
drivers/kw2xrf/include/kw2xrf_tm.h

@ -0,0 +1,47 @@
/*
* Copyright (C) 2016 Phytec Messtechnik GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests_kw2xrf
* @{
*
* @file
* @brief Testing interfaces for kw2xrf driver
*
* @author Johann Fischer <j.fischer@phytec.de>
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef KW2XRF_TESTMODE
#include "kw2xrf.h"
#include "kw2xrf_reg.h"
#include "kw2xrf_getset.h"
#include "net/netopt.h"
enum mkw2xrf_testmode {
KW2XRF_TM_CTX_PREAMBLE = NETOPT_RF_TESTMODE_CTX_PRBS9 + 1,
KW2XRF_TM_CTX_2MHZ,
KW2XRF_TM_CTX_200KHZ,
KW2XRF_TM_CTX_1MBPS_PRBS9,
KW2XRF_TM_CTX_EXT,
KW2XRF_TM_CTX_NM0,
KW2XRF_TM_CTX_NM1,
};
int kw2xrf_set_test_mode(kw2xrf_t *dev, uint8_t mode);
#endif
#ifdef __cplusplus
}
#endif
/** @} */

308
drivers/kw2xrf/include/overwrites.h

@ -0,0 +1,308 @@
/*!
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* \file MCR20Overwrites.h
* Description: Overwrites header file for MCR20 Register values
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OVERWRITES_H_
#define OVERWRITES_H_
typedef struct overwrites_tag {
char address;
char data;
} overwrites_t;
/*****************************************************************************************************************/
// This file is created exclusively for use with the transceiver 2.0 silicon
// and is provided for the world to use. It contains a list of all
// known overwrite values. Overwrite values are non-default register
// values that configure the transceiver device to a more optimally performing
// posture. It is expected that low level software (i.e. PHY) will
// consume this file as a #include, and transfer the contents to the
// the indicated addresses in the transceiver's memory space. This file has
// at least one required entry, that being its own version current version
// number, to be stored at transceiver's location 0x3B the
// OVERWRITES_VERSION_NUMBER register. The RAM register is provided in
// the transceiver address space to assist in future debug efforts. The
// analyst may read this location (once device has been booted with
// mysterious software) and have a good indication of what register
// overwrites were performed (with all versions of the overwrites.h file
// being archived forever at the Compass location shown above.
//
// The transceiver has an indirect register (IAR) space. Write access to this space
// requires 3 or more writes:
// 1st) the first write is an index value to the indirect (write Bit7=0, register access Bit 6=0) + 0x3E
// 2nd) IAR Register #0x00 - 0xFF.
// 3rd) The data to write
// nth) Burst mode additional data if required.
//
// Write access to direct space requires only a single address, data pair.
overwrites_t const overwrites_direct[] ={
{0x3B, 0x0C}, //version 0C: new value for ACKDELAY targeting 198us (23 May, 2013, Larry Roshak)
{0x23, 0x17} //PA_PWR new default Power Step is "23"
};
overwrites_t const overwrites_indirect[] ={
{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents)
{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3
{0x92, 0x07}, //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1
{0x8A, 0x71}, //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
{0x79, 0x2F}, //CHF_IBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7A, 0x2F}, //CHF_QBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7B, 0x24}, //CHF_IRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7C, 0x24}, //CHF_QRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7D, 0x24}, //CHF_IL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7E, 0x24}, //CHF_QL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7F, 0x32}, //CHF_CC1 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x80, 0x1D}, //CHF_CCL Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x81, 0x2D}, //CHF_CC2 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x82, 0x24}, //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x83, 0x24}, //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x64, 0x28}, //PA_CAL_DIS=1 Disabled PA calibration
{0x52, 0x55}, //AGC_THR1 RSSI tune up
{0x53, 0x2D}, //AGC_THR2 RSSI tune up
{0x66, 0x5F}, //ATT_RSSI1 tune up
{0x67, 0x8F}, //ATT_RSSI2 tune up
{0x68, 0x61}, //RSSI_OFFSET
{0x78, 0x03}, //CHF_PMAGAIN
{0x22, 0x50}, //CCA1_THRESH
{0x4D, 0x13}, //CORR_NVAL moved from 0x14 to 0x13 for 0.5 dB improved Rx Sensitivity
{0x39, 0x3D} //ACKDELAY new value targeting a delay of 198us (23 May, 2013, Larry Roshak)
};
/* begin of deprecated versions
==VERSION 1==
(version 1 is empty)
==VERSION 2==
overwrites_t const overwrites_indirect[] ={
{0x31, 0x02} //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents)
};
==VERSION 3==
overwrites_t const overwrites_indirect[] ={
{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents)
{0x91, 0xB3}, //VCO_CTRL1: override VCOALC_REF_TX to 3
{0x92, 0x07} //VCO_CTRL2: override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1
};
==VERSION 4==
overwrites_t const overwrites_direct[] ={
{0x3B, 0x04} //version 04 is the current version: update PA_COILTUNING default
};
overwrites_t const overwrites_indirect[] ={
{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents)
{0x91, 0xB3}, //VCO_CTRL1: override VCOALC_REF_TX to 3
{0x92, 0x07} //VCO_CTRL2: override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1
{0x8A, 0x71} //PA_TUNING: override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
};
==VERSION 5==
overwrites_t const overwrites_direct[] ={
{0x3B, 0x05} //version 05: updates Channel Filter Register set (21 Dec 2012, on behalf of S. Soca)
};
overwrites_t const overwrites_indirect[] ={
{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents)
{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3
{0x92, 0x07} //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1
{0x8A, 0x71} //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
{0x79, 0x2F} //CHF_IBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7A, 0x2F} //CHF_QBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7B, 0x24} //CHF_IRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7C, 0x24} //CHF_QRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7D, 0x24} //CHF_IL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7E, 0x24} //CHF_QL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x82, 0x24} //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x83, 0x24} //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7F, 0x32} //CHF_CC1 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x80, 0x1D} //CHF_CCL Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x81, 0x2D} //CHF_CC2 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
};
==VERSION 6==
overwrites_t const overwrites_direct[] ={
{0x3B, 0x06} //version 06: disable PA calibration
};
overwrites_t const overwrites_indirect[] ={
{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents)
{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3
{0x92, 0x07} //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1
{0x8A, 0x71} //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
{0x79, 0x2F} //CHF_IBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7A, 0x2F} //CHF_QBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7B, 0x24} //CHF_IRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7C, 0x24} //CHF_QRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7D, 0x24} //CHF_IL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7E, 0x24} //CHF_QL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x82, 0x24} //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x83, 0x24} //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7F, 0x32} //CHF_CC1 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x80, 0x1D} //CHF_CCL Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x81, 0x2D} //CHF_CC2 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x64, 0x28} //PA_CAL_DIS=1 Disabled PA calibration
};
==VERSION 7==
overwrites_t const overwrites_direct[] ={
{0x3B, 0x07} //version 07: updated registers for ED/RSSI
};
overwrites_t const overwrites_indirect[] ={
{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents)
{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3
{0x92, 0x07}, //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1
{0x8A, 0x71}, //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
{0x79, 0x2F}, //CHF_IBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7A, 0x2F}, //CHF_QBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7B, 0x24}, //CHF_IRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7C, 0x24}, //CHF_QRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7D, 0x24}, //CHF_IL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7E, 0x24}, //CHF_QL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x82, 0x24}, //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x83, 0x24}, //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7F, 0x32}, //CHF_CC1 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x80, 0x1D}, //CHF_CCL Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x81, 0x2D}, //CHF_CC2 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x64, 0x28}, //PA_CAL_DIS=1 Disabled PA calibration
{0x52, 0x73}, //AGC_THR1 RSSI tune up
{0x53, 0x2D}, //AGC_THR2 RSSI tune up
{0x66, 0x5F}, //ATT_RSSI1 tune up
{0x67, 0x8F}, //ATT_RSSI2 tune up
{0x68, 0x60}, //RSSI_OFFSET
{0x69, 0x65} //RSSI_SLOPE
};
==VERSION 8==
overwrites_t const overwrites_direct[] ={
{0x3B, 0x08} //version 08: updated registers for ED/RSSI
};
overwrites_t const overwrites_indirect[] ={
{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents)
{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3
{0x92, 0x07}, //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1
{0x8A, 0x71}, //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
{0x79, 0x2F}, //CHF_IBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7A, 0x2F}, //CHF_QBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7B, 0x24}, //CHF_IRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7C, 0x24}, //CHF_QRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7D, 0x24}, //CHF_IL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7E, 0x24}, //CHF_QL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x82, 0x24}, //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x83, 0x24}, //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7F, 0x32}, //CHF_CC1 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x80, 0x1D}, //CHF_CCL Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x81, 0x2D}, //CHF_CC2 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x64, 0x28}, //PA_CAL_DIS=1 Disabled PA calibration
{0x52, 0x73}, //AGC_THR1 RSSI tune up
{0x53, 0x2D}, //AGC_THR2 RSSI tune up
{0x66, 0x5F}, //ATT_RSSI1 tune up
{0x67, 0x8F}, //ATT_RSSI2 tune up
{0x69, 0x65} //RSSI_SLOPE
{0x68, 0x61}, //RSSI_OFFSET
{0x78, 0x03} //CHF_PMAGAIN
};
==VERSION 9==
overwrites_t const overwrites_direct[] ={
{0x3B, 0x09} //version 09: updated registers for ED/RSSI and PowerStep
{0x23, 0x17} //PA_PWR new default value
};
overwrites_t const overwrites_indirect[] ={
{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents)
{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3
{0x92, 0x07}, //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1
{0x8A, 0x71}, //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
{0x79, 0x2F}, //CHF_IBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7A, 0x2F}, //CHF_QBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7B, 0x24}, //CHF_IRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7C, 0x24}, //CHF_QRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7D, 0x24}, //CHF_IL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7E, 0x24}, //CHF_QL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7F, 0x32}, //CHF_CC1 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x80, 0x1D}, //CHF_CCL Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x81, 0x2D}, //CHF_CC2 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x82, 0x24}, //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x83, 0x24}, //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x64, 0x28}, //PA_CAL_DIS=1 Disabled PA calibration
{0x52, 0x55}, //AGC_THR1 RSSI tune up
{0x53, 0x2D}, //AGC_THR2 RSSI tune up
{0x66, 0x5F}, //ATT_RSSI1 tune up
{0x67, 0x8F}, //ATT_RSSI2 tune up
{0x68, 0x61}, //RSSI_OFFSET
{0x78, 0x03} //CHF_PMAGAIN
};
==VERSION A==
overwrites_t const overwrites_direct[] ={
{0x3B, 0x0A} //version 0A: updated registers for CCA
{0x23, 0x17} //PA_PWR new default Power Step is "23"
};
overwrites_t const overwrites_indirect[] ={
{0x31, 0x02}, //clear MISO_HIZ_EN (for single SPI master/slave pair) and SPI_PUL_EN (minimize HIB currents)
{0x91, 0xB3}, //VCO_CTRL1 override VCOALC_REF_TX to 3
{0x92, 0x07}, //VCO_CTRL2 override VCOALC_REF_RX to 3, keep VCO_BUF_BOOST = 1
{0x8A, 0x71}, //PA_TUNING override PA_COILTUNING to 001 (27 Nov 2012, D. Brown, on behalf of S. Eid)
{0x79, 0x2F}, //CHF_IBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7A, 0x2F}, //CHF_QBUF Adjust the gm-C filter gain (+/- 6dB) (21 Dec, 2012, on behalf of S. Soca)
{0x7B, 0x24}, //CHF_IRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7C, 0x24}, //CHF_QRIN Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7D, 0x24}, //CHF_IL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7E, 0x24}, //CHF_QL Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x7F, 0x32}, //CHF_CC1 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x80, 0x1D}, //CHF_CCL Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x81, 0x2D}, //CHF_CC2 Adjust the filter center frequency (+/- 1MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x82, 0x24}, //CHF_IROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x83, 0x24}, //CHF_QROUT Adjust the filter bandwidth (+/- 0.5MHz) (21 Dec, 2012, on behalf of S. Soca)
{0x64, 0x28}, //PA_CAL_DIS=1 Disabled PA calibration
{0x52, 0x55}, //AGC_THR1 RSSI tune up
{0x53, 0x2D}, //AGC_THR2 RSSI tune up
{0x66, 0x5F}, //ATT_RSSI1 tune up
{0x67, 0x8F}, //ATT_RSSI2 tune up
{0x68, 0x61}, //RSSI_OFFSET
{0x78, 0x03} //CHF_PMAGAIN
{0x22, 0x50} //CCA1_THRESH
};
end of deprecated versions */
#endif //OVERWRITES_H_

1311
drivers/kw2xrf/kw2xrf.c

File diff suppressed because it is too large Load Diff

516
drivers/kw2xrf/kw2xrf_getset.c

@ -0,0 +1,516 @@
/*
* Copyright (C) 2016 PHYTEC Messtechnik GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup drivers_kw2xrf
* @{
* @file
* @brief get/set functionality of kw2xrf driver
*
* @author Johann Fischer <j.fischer@phytec.de>
* @author Jonas Remmert <j.remmert@phytec.de>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @}
*/
#include "kw2xrf.h"
#include "kw2xrf_spi.h"
#include "kw2xrf_reg.h"
#include "kw2xrf_getset.h"
#include "kw2xrf_intern.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#define KW2XRF_LQI_HW_MAX 230 /**< LQI Saturation Level */
/* Modem_PA_PWR Register (PA Power Control) has a valid range from 3-31 */
#define MKW2XDRF_PA_RANGE_MAX 31 /**< Maximum value of PA Power Control Register */
#define MKW2XDRF_PA_RANGE_MIN 3 /**< Minimum value of PA Power Control Register */
/* PLL integer and fractional lookup tables
*
* Fc = 2405 + 5(k - 11) , k = 11,12,...,26
*
* Equation for PLL frequency, MKW2xD Reference Manual, p.255 :
* F = ((PLL_INT0 + 64) + (PLL_FRAC0/65536))32MHz
*
*/
static const uint8_t pll_int_lt[16] = {
11, 11, 11, 11,
11, 11, 12, 12,
12, 12, 12, 12,
13, 13, 13, 13
};
static const uint16_t pll_frac_lt[16] = {
10240, 20480, 30720, 40960,
51200, 61440, 6144, 16384,
26624, 36864, 47104, 57344,
2048, 12288, 22528, 32768
};
static const uint8_t pow_lt[44] = {
3, 4, 4, 5,
6, 6, 7, 7,
8, 9, 9, 10,
11, 11, 12, 13,
13, 14, 14, 15,
16, 16, 17, 18,
18, 19, 20, 20,
21, 21, 22, 23,
23, 24, 25, 25,
26, 27, 27, 28,
28, 29, 30, 31
};
void kw2xrf_set_tx_power(kw2xrf_t *dev, int16_t txpower)
{
if (txpower > MKW2XDRF_OUTPUT_POWER_MAX) {
txpower = MKW2XDRF_OUTPUT_POWER_MAX;
}
if (txpower < MKW2XDRF_OUTPUT_POWER_MIN) {
txpower = MKW2XDRF_OUTPUT_POWER_MIN;
}
uint8_t level = pow_lt[txpower - MKW2XDRF_OUTPUT_POWER_MIN];
kw2xrf_write_dreg(dev, MKW2XDM_PA_PWR, MKW2XDM_PA_PWR(level));
dev->tx_power = txpower;
}
uint16_t kw2xrf_get_txpower(kw2xrf_t *dev)
{
return dev->tx_power;
}
uint8_t kw2xrf_get_channel(kw2xrf_t *dev)
{
uint8_t pll_int = kw2xrf_read_dreg(dev, MKW2XDM_PLL_INT0);
uint16_t pll_frac = kw2xrf_read_dreg(dev, MKW2XDM_PLL_FRAC0_LSB);
pll_frac |= ((uint16_t)kw2xrf_read_dreg(dev, MKW2XDM_PLL_FRAC0_MSB) << 8);
for (int i = 0; i < 16; i++) {
if ((pll_frac_lt[i] == pll_frac) && (pll_int_lt[i] == pll_int)) {
return i + 11;
}
}
return 0;
}
static int kw2xrf_get_sequence(kw2xrf_t *dev)
{
int reg = 0;
reg = kw2xrf_read_dreg(dev, MKW2XDM_PHY_CTRL1);
reg &= MKW2XDM_PHY_CTRL1_XCVSEQ_MASK;
return reg;
}
int kw2xrf_set_channel(kw2xrf_t *dev, uint8_t channel)
{
/* Save old sequence to restore this state later */
uint8_t old_seq = kw2xrf_get_sequence(dev);
if (channel < KW2XRF_MIN_CHANNEL || channel > KW2XRF_MAX_CHANNEL) {
DEBUG("[kw2xrf]: Invalid channel %i set\n", channel);
return -1;
}
if (old_seq) {
kw2xrf_abort_sequence(dev);
}
uint8_t tmp = channel - 11;
kw2xrf_write_dreg(dev, MKW2XDM_PLL_INT0, MKW2XDM_PLL_INT0_VAL(pll_int_lt[tmp]));
kw2xrf_write_dreg(dev, MKW2XDM_PLL_FRAC0_LSB, (uint8_t)pll_frac_lt[tmp]);
kw2xrf_write_dreg(dev, MKW2XDM_PLL_FRAC0_MSB, (uint8_t)(pll_frac_lt[tmp] >> 8));
dev->netdev.chan = channel;
if (old_seq) {
kw2xrf_set_sequence(dev, old_seq);
}
DEBUG("[kw2xrf]: set channel to %u\n", channel);
return 0;
}