Browse Source

drivers/mrf24j40: initial mrf24j40 support

pr/spi.typo
Koen Zandberg 6 years ago
parent
commit
672da2c457
  1. 13
      drivers/Makefile.dep
  2. 3
      drivers/Makefile.include
  3. 412
      drivers/include/mrf24j40.h
  4. 1
      drivers/mrf24j40/Makefile
  5. 142
      drivers/mrf24j40/include/mrf24j40_internal.h
  6. 41
      drivers/mrf24j40/include/mrf24j40_netdev.h
  7. 74
      drivers/mrf24j40/include/mrf24j40_params.h
  8. 454
      drivers/mrf24j40/include/mrf24j40_registers.h
  9. 168
      drivers/mrf24j40/mrf24j40.c
  10. 490
      drivers/mrf24j40/mrf24j40_getset.c
  11. 255
      drivers/mrf24j40/mrf24j40_internal.c
  12. 569
      drivers/mrf24j40/mrf24j40_netdev.c
  13. 22
      pkg/lwip/contrib/lwip.c
  14. 5
      sys/auto_init/auto_init.c
  15. 75
      sys/auto_init/netif/auto_init_mrf24j40.c

13
drivers/Makefile.dep

@ -19,6 +19,19 @@ ifneq (,$(filter at86rf2%,$(USEMODULE)))
endif
endif
ifneq (,$(filter mrf24j40,$(USEMODULE)))
USEMODULE += xtimer
USEMODULE += uuid
USEMODULE += netif
USEMODULE += ieee802154
USEMODULE += netdev2_ieee802154
ifneq (,$(filter gnrc_netdev_default,$(USEMODULE)))
# 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
ifneq (,$(filter bh1750fvi,$(USEMODULE)))
USEMODULE += xtimer
FEATURES_REQUIRED += periph_i2c

3
drivers/Makefile.include

@ -4,6 +4,9 @@ endif
ifneq (,$(filter at86rf2xx,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/at86rf2xx/include
endif
ifneq (,$(filter mrf24j40,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/mrf24j40/include
endif
ifneq (,$(filter cc110x,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/cc110x/include
endif

412
drivers/include/mrf24j40.h

@ -0,0 +1,412 @@
/*
* Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
* Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
*
* 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.
*/
/**
* @defgroup drivers_mrf24j40 MRF24J40 based drivers
* @ingroup drivers_netdev_netdev2
*
* This module contains drivers for radio devices in Microchip MRF24J40 series.
* The driver is aimed to work with all devices of this series.
*
* @{
*
* @file
* @brief Interface definition for MRF24J40 based drivers
*
* @author Neo Nenaco <neo@nenaco.de>
* @author Koen Zandberg <koen@bergzand.net>
*/
#ifndef MRF24J40_H
#define MRF24J40_H
#include <stdint.h>
#include "board.h"
#include "periph/spi.h"
#include "periph/gpio.h"
#include "net/netdev2.h"
#include "net/netdev2/ieee802154.h"
#include "net/gnrc/nettype.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Default TX power (0dBm)
* 0 -> -36dB
* 1 -> -35dB
* 2 -> -34dB
* 3 -> -33dB
* 4 -> -32dB
* 5 -> -31dB
* 6 -> -30dB
* 7 -> -30dB
* 8 -> -26dB
* 9 -> -25dB
* 10 -> -24dB
* 11 -> -23dB
* 12 -> -22dB
* 13 -> -21dB
* 14 -> -20dB
* 15 -> -20dB
* 16 -> -16dB
* 17 -> -15dB
* 18 -> -14dB
* 19 -> -13dB
* 20 -> -12dB
* 21 -> -11dB
* 22 -> -10dB
* 23 -> -10dB
* 24 -> -6dB
* 25 -> -5dB
* 26 -> -4dB
* 27 -> -3dB
* 28 -> -2dB
* 29 -> -1dB
* 30 -> -0dB
* 31 -> -0dB
*/
/**
* @brief Base (minimal) RSSI value in dBm
*/
#define RSSI_BASE_VAL (-91)
/**
* @brief Flags for PSEUDO DEVICE INTERNAL STATES
* @{
*/
#define MRF24J40_PSEUDO_STATE_IDLE (0x01) /**< Idle, ready to transmit or receive */
#define MRF24J40_PSEUDO_STATE_SLEEP (0x02) /**< sleep mode, registers functional, but no RF */
#define MRF24J40_PSEUDO_STATE_RESET (0x04) /**< Reset device, next state is idle */
/** @} */
/**
* @brief Internal device option flags
*
* `0x00ff` is reserved for general IEEE 802.15.4 flags
* (see @ref netdev2_ieee802154_t)
*
* @{
*/
#define MRF24J40_OPT_CSMA (0x0100) /**< CSMA active */
#define MRF24J40_OPT_PROMISCUOUS (0x0200) /**< promiscuous mode
* active */
#define MRF24J40_OPT_PRELOADING (0x0400) /**< preloading enabled */
#define MRF24J40_OPT_TELL_TX_START (0x0800) /**< notify MAC layer on TX
* start */
#define MRF24J40_OPT_TELL_TX_END (0x1000) /**< notify MAC layer on TX
* finished */
#define MRF24J40_OPT_TELL_RX_START (0x2000) /**< notify MAC layer on RX
* start */
#define MRF24J40_OPT_TELL_RX_END (0x4000) /**< notify MAC layer on RX
* finished */
#define MRF24J40_OPT_REQ_AUTO_ACK (0x8000) /**< notify MAC layer on RX
* finished */
/** @} */
#define MRF24J40_TASK_TX_DONE (0x01) /**< TX operation is done */
#define MRF24J40_TASK_TX_READY (0x02) /**< TX operation results ready for processing */
#define MRF24J40_TASK_RX_READY (0x04) /**< RX processing needed */
#define MRF24J40_MAX_FRAME_RETRIES (3U) /**< Number of frame retries (fixed) */
/**
* @brief struct holding all params needed for device initialization
*/
typedef struct mrf24j40_params {
spi_t spi; /**< SPI bus the device is connected to */
spi_clk_t spi_clk; /**< SPI speed to use */
spi_cs_t cs_pin; /**< GPIO pin connected to chip select */
gpio_t int_pin; /**< GPIO pin connected to the interrupt pin */
gpio_t reset_pin; /**< GPIO pin connected to the reset pin */
} mrf24j40_params_t;
/**
* @brief Device descriptor for MRF24J40 radio devices
*/
typedef struct {
netdev2_ieee802154_t netdev; /**< netdev2 parent struct */
/**
* @brief device specific fields
* @{
*/
mrf24j40_params_t params; /**< parameters for initialization */
uint8_t state; /**< current state of the radio */
uint8_t idle_state; /**< state to return to after sending */
uint8_t tx_frame_len; /**< length of the current TX frame */
uint8_t header_len;
uint8_t pending; /**< Flags for pending tasks */
uint8_t irq_flag;
} mrf24j40_t;
/**
* @brief Setup an MRF24J40 based device state
*
* @param[out] dev device descriptor
* @param[in] params parameters for device initialization
*/
void mrf24j40_setup(mrf24j40_t *dev, const mrf24j40_params_t *params);
/**
* @brief Trigger a hardware reset and configure radio with default values
*
* @param[in] dev device to reset
*/
void mrf24j40_reset(mrf24j40_t *dev);
/**
* @brief Trigger a clear channel assessment
*
* @param[in] dev device to use
*
* @return true if channel is clear
* @return false if channel is busy
*/
bool mrf24j40_cca(mrf24j40_t *dev);
/**
* @brief Get the short address of the given device
*
* @param[in] dev device to read from
*
* @return the currently set (2-byte) short address
*/
uint16_t mrf24j40_get_addr_short(mrf24j40_t *dev);
/**
* @brief Set the short address of the given device
*
* @param[in] dev device to write to
* @param[in] addr (2-byte) short address to set
*/
void mrf24j40_set_addr_short(mrf24j40_t *dev, uint16_t addr);
/**
* @brief Get the configured long address of the given device
*
* @param[in] dev device to read from
*
* @return the currently set (8-byte) long address
*/
uint64_t mrf24j40_get_addr_long(mrf24j40_t *dev);
/**
* @brief Set the long address of the given device
*
* @param[in] dev device to write to
* @param[in] addr (8-byte) long address to set
*/
void mrf24j40_set_addr_long(mrf24j40_t *dev, uint64_t addr);
/**
* @brief Get the configured channel number of the given device
*
* @param[in] dev device to read from
*
* @return the currently set channel number
*/
uint8_t mrf24j40_get_chan(mrf24j40_t *dev);
/**
* @brief Set the channel number of the given device
*
* @param[in] dev device to write to
* @param[in] chan channel number to set
*/
void mrf24j40_set_chan(mrf24j40_t *dev, uint8_t chan);
/**
* @brief Get the configured PAN ID of the given device
*
* @param[in] dev device to read from
*
* @return the currently set PAN ID
*/
uint16_t mrf24j40_get_pan(mrf24j40_t *dev);
/**
* @brief Set the PAN ID of the given device
*
* @param[in] dev device to write to
* @param[in] pan PAN ID to set
*/
void mrf24j40_set_pan(mrf24j40_t *dev, uint16_t pan);
/**
* @brief Get the configured transmission power of the given device [in dBm]
*
* @param[in] dev device to read from
*
* @return configured transmission power in dBm
*/
int16_t mrf24j40_get_txpower(mrf24j40_t *dev);
/**
* @brief Set the transmission power of the given device [in dBm]
*
* If the device does not support the exact dBm value given, it will set a value
* as close as possible to the given value. If the given value is larger or
* lower then the maximal or minimal possible value, the min or max value is
* set, respectively.
*
* @param[in] dev device to write to
* @param[in] txpower transmission power in dBm
*/
void mrf24j40_set_txpower(mrf24j40_t *dev, int16_t txpower);
/**
* @brief Get the maximum number of channel access attempts per frame (CSMA)
*
* @param[in] dev device to read from
*
* @return configured number of retries
*/
uint8_t mrf24j40_get_csma_max_retries(mrf24j40_t *dev);
/**
* @brief Set the maximum number of channel access attempts per frame (CSMA)
*
* This setting specifies the number of attempts to access the channel to
* transmit a frame. If the channel is busy @p retries times, then frame
* transmission fails.
* Valid values: 0 to 5, -1 means CSMA disabled
*
* @param[in] dev device to write to
* @param[in] retries the maximum number of retries
*/
void mrf24j40_set_csma_max_retries(mrf24j40_t *dev, int8_t retries);
/**
* @brief Set the min and max backoff exponent for CSMA/CA
*
* - Maximum BE: 0 - 8
* - Minimum BE: 0 - [max]
*
* @param[in] dev device to write to
* @param[in] min the minimum BE
* @param[in] max the maximum BE
*/
void mrf24j40_set_csma_backoff_exp(mrf24j40_t *dev, uint8_t min, uint8_t max);
/**
* @brief Get the CCA threshold value
*
* @param[in] dev device to read value from
*
* @return the current CCA threshold value
*/
int8_t mrf24j40_get_cca_threshold(mrf24j40_t *dev);
/**
* @brief Set the CCA threshold value
*
* @param[in] dev device to write to
* @param[in] value the new CCA threshold value
*/
void mrf24j40_set_cca_threshold(mrf24j40_t *dev, int8_t value);
/**
* @brief Enable or disable driver specific options
*
* @param[in] dev device to set/clear option flag for
* @param[in] option option to enable/disable
* @param[in] state true for enable, false for disable
*/
void mrf24j40_set_option(mrf24j40_t *dev, uint16_t option, bool state);
/**
* @brief Set the state of the given device (trigger a state change)
*
* @param[in] dev device to change state of
* @param[in] state the targeted new state
*/
void mrf24j40_set_state(mrf24j40_t *dev, uint8_t state);
/**
* @brief Put in sleep mode
*
* @param[in] dev device to put to sleep
*/
void mrf24j40_sleep(mrf24j40_t *dev);
/**
* @brief Put in sleep mode if idle_state is sleep
*
* @param[in] dev device to put to sleep
*/
void mrf24j40_assert_sleep(mrf24j40_t *dev);
/**
* @brief Wake up from sleep mode
*
* @param[in] dev device to eventually wake up
*/
void mrf24j40_assert_awake(mrf24j40_t *dev);
/**
* @brief Reset the internal state machine to TRX_OFF mode.
*
* This will force a transition to TRX_OFF regardless of whether the transceiver
* is currently busy sending or receiving. This function is used to get back to
* a known state during driver initialization.
*
* @param[in] dev device to operate on
*/
void mrf24j40_reset_state_machine(mrf24j40_t *dev);
/**
* @brief Software Reset.
*
* This will force the power management circuitry, the baseband circuitry and the MAC circuitry
* to be reset
*
* @param[in] dev device to operate on
*/
void mrf24j40_software_reset(mrf24j40_t *dev);
/**
* @brief Prepare for sending of data
*
* This function puts the given device into the TX state, so no receiving of
* data is possible after it was called.
*
* @param[in] dev device to prepare for sending
*/
void mrf24j40_tx_prepare(mrf24j40_t *dev);
/**
* @brief Load chunks of data into the transmit buffer of the given device
*
* @param[in] dev device to write data to
* @param[in] data buffer containing the data to load
* @param[in] len number of bytes in @p buffer
* @param[in] offset offset used when writing data to internal buffer
*
* @return offset + number of bytes written
*/
size_t mrf24j40_tx_load(mrf24j40_t *dev, uint8_t *data, size_t len,
size_t offset);
/**
* @brief Trigger sending of data previously loaded into transmit buffer
*
* @param[in] dev device to trigger
*/
void mrf24j40_tx_exec(mrf24j40_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* MRF24J40_H */
/** @} */

1
drivers/mrf24j40/Makefile

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

142
drivers/mrf24j40/include/mrf24j40_internal.h

@ -0,0 +1,142 @@
/*
* Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
* Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
*
* 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_mrf24j40
* @{
*
* @file
* @brief Internal interfaces for MRF24J40 drivers
*
* @author Neo Nenaco <neo@nenaco.de>
* @author Koen Zandberg <koen@bergzand.net>
*/
#ifndef MRF24J40_INTERNAL_H
#define MRF24J40_INTERNAL_H
#include <stdint.h>
#include "mrf24j40.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief initialization as decribed in datasheet
*/
void mrf24j40_init(mrf24j40_t *dev);
/**
* @brief Read from a register with a at address `addr` from device `dev`. Register with 8bit address
*
* @param[in] dev device to read from
* @param[in] addr address of the register to read
*
* @return the value of the specified register
*/
uint8_t mrf24j40_reg_read_short(mrf24j40_t *dev, const uint8_t addr);
/**
* @brief Write to a register at address `addr` from device `dev`. Register with 8bit address
*
* @param[in] dev device to write to
* @param[in] addr address of the register to write
* @param[in] value value to write to the given register
*/
void mrf24j40_reg_write_short(mrf24j40_t *dev, const uint8_t addr, const uint8_t value);
/**
* @brief Read from a register with a at address `addr` from device `dev`. Register with 10bit address
*
* @param[in] dev device to read from
* @param[in] addr address of the register to read
*
* @return the value of the specified register
*/
uint8_t mrf24j40_reg_read_long(mrf24j40_t *dev, const uint16_t addr);
/**
* @brief Write to a register at address `addr` from device `dev`. Register with 10bit address
*
* @param[in] dev device to write to
* @param[in] addr address of the register to write
* @param[in] value value to write to the given register
*/
void mrf24j40_reg_write_long(mrf24j40_t *dev, const uint16_t addr, const uint8_t value);
/**
* @brief Read a chunk of data from the TX Normal FIFO area of the given device
*
* @param[in] dev device to read from
* @param[in] offset starting address to read from [valid 0x00-0x1ff]
* @param[out] data buffer to read data into
* @param[in] len number of bytes to read from FIFO
*/
void mrf24j40_tx_normal_fifo_read(mrf24j40_t *dev, const uint16_t offset, uint8_t *data, const size_t len);
/**
* @brief Write a chunk of data into the TX Normal FIFO area of the given device
*
* @param[in] dev device to write to
* @param[in] offset address in the TX Normal FIFO to write to [valid 0x00-0x1ff]
* @param[in] data data to copy into FIFO
* @param[in] len number of bytes to write to FIFO
*/
void mrf24j40_tx_normal_fifo_write(mrf24j40_t *dev, const uint16_t offset, const uint8_t *data, const size_t len);
/**
* @brief Read a chunk of data from the RX_FIFO area of the given device
*
* @param[in] dev device to read from
* @param[in] offset starting address to read from [valid 0x00-0x1ff]
* @param[out] data buffer to read data into
* @param[in] len number of bytes to read from FIFO
*/
void mrf24j40_rx_fifo_read(mrf24j40_t *dev, const uint16_t offset, uint8_t *data, const size_t len);
/**
* @brief Write a chunk of data into the RX_FIFO area of the given device
*
* @param[in] dev device to write to
* @param[in] offset address in the RX FIFO to write to [valid 0x00-0x1ff]
* @param[in] data data to copy into FIFO
* @param[in] len number of bytes to write to FIFO
*/
void mrf24j40_rx_fifo_write(mrf24j40_t *dev, const uint16_t offset, const uint8_t *data, const size_t len);
/**
* @brief Reset the pending task list of a device
*
* @param[in] dev device to reset tasks of
*/
void mrf24j40_reset_tasks(mrf24j40_t *dev);
/**
* @brief Check for pending interrupts and update task list
*
* @param[in] dev device to read
*/
void mrf24j40_update_tasks(mrf24j40_t *dev);
/**
* @brief Trigger a hardware reset
*
* @param[in] dev device to reset
*/
void mrf24j40_hardware_reset(mrf24j40_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* MRF24J40_INTERNAL_H */
/** @} */

41
drivers/mrf24j40/include/mrf24j40_netdev.h

@ -0,0 +1,41 @@
/*
* Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
* Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
*
* 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_mrf24j40
* @{
*
* @file
* @brief Netdev interface to MRF24J40 drivers
*
* @author Neo Nenaco <neo@nenaco.de>
* @author Koen Zandberg <koen@bergzand.net>
*/
#ifndef MRF24J40_NETDEV_H
#define MRF24J40_NETDEV_H
#include "net/netdev2.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Reference to the netdev device driver struct
*/
extern const netdev2_driver_t mrf24j40_driver;
#ifdef __cplusplus
}
#endif
#endif /* MRF24J40_NETDEV_H */
/** @} */

74
drivers/mrf24j40/include/mrf24j40_params.h

@ -0,0 +1,74 @@
/*
* Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
* Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
*
* 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_mrf24j40
*
* @{
* @file
* @brief Default configuration for the MRF24J40 driver
*
* @author Neo Nenaco <neo@nenaco.de>
* @author Koen Zandberg <koen@bergzand.net>
*/
#ifndef MRF24J40_PARAMS_H
#define MRF24J40_PARAMS_H
#include "board.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set default configuration parameters for the MRF24J40 driver
* @{
*/
#ifndef MRF24J40_PARAM_SPI
#define MRF24J40_PARAM_SPI (SPI_DEV(0))
#endif
#ifndef MRF24J40_PARAM_SPI_CLK
#define MRF24J40_PARAM_SPI_CLK (SPI_CLK_5MHZ)
#endif
#ifndef MRF24J40_PARAM_CS
#define MRF24J40_PARAM_CS (GPIO_PIN(0, 0))
#endif
#ifndef MRF24J40_PARAM_INT
#define MRF24J40_PARAM_INT (GPIO_PIN(0, 1))
#endif
#ifndef MRF24J40_PARAM_RESET
#define MRF24J40_PARAM_RESET (GPIO_PIN(0, 3))
#endif
#define MRF24J40_PARAMS_DEFAULT { .spi = MRF24J40_PARAM_SPI, \
.spi_clk = MRF24J40_PARAM_SPI_CLK, \
.cs_pin = MRF24J40_PARAM_CS, \
.int_pin = MRF24J40_PARAM_INT, \
.reset_pin = MRF24J40_PARAM_RESET }
/**@}*/
/**
* @brief MRF24J40 configuration
*/
static const mrf24j40_params_t mrf24j40_params[] =
{
#ifdef MRF24J40_PARAMS_BOARD
MRF24J40_PARAMS_BOARD,
#else
MRF24J40_PARAMS_DEFAULT,
#endif
};
#ifdef __cplusplus
}
#endif
#endif /* MRF24J40_PARAMS_H */
/** @} */

454
drivers/mrf24j40/include/mrf24j40_registers.h

@ -0,0 +1,454 @@
/*
* Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
* Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
*
* 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_mrf24j40
* @{
*
* @file
* @brief Register and command definitions for MRF24J40 devices
*
* @author Neo Nenaco <neo@nenaco.de>
* @author Koen Zandberg <koen@bergzand.net>
*/
#ifndef MRF24J40_REGISTERS_H
#define MRF24J40_REGISTERS_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief SPI access specifiers
* @{
*/
#define MRF24J40_SHORT_ADDR_TRANS (0x00)
#define MRF24J40_LONG_ADDR_TRANS (0x80)
#define MRF24J40_ACCESS_READ (0x00)
#define MRF24J40_ACCESS_WRITE (0x01)
#define MRF24J40_ACCESS_WRITE_LNG (0x10)
#define MRF24J40_ADDR_OFFSET (0x01)
/** @} */
/**
* @brief FIFO-Address-Map
****@{
*/
#define MRF24J40_TX_NORMAL_FIFO (0x000)
#define MRF24J40_TX_BEACON_FIFO (0x080)
#define MRF24J40_TX_GTS1_FIFO (0x100)
#define MRF24J40_TX_GTS2_FIFO (0x180)
#define MRF24J40_RX_FIFO (0x300)
/** @} */
/**
* @brief Short-Register addresses
* @{
*/
#define MRF24J40_REG_RXMCR (0x00)
#define MRF24J40_REG_PANIDL (0x01)
#define MRF24J40_REG_PANIDH (0x02)
#define MRF24J40_REG_SADRL (0x03)
#define MRF24J40_REG_SADRH (0x04)
#define MRF24J40_REG_EADR0 (0x05)
#define MRF24J40_REG_EADR1 (0x06)
#define MRF24J40_REG_EADR2 (0x07)
#define MRF24J40_REG_EADR3 (0x08)
#define MRF24J40_REG_EADR4 (0x09)
#define MRF24J40_REG_EADR5 (0x0A)
#define MRF24J40_REG_EADR6 (0x0B)
#define MRF24J40_REG_EADR7 (0x0C)
#define MRF24J40_REG_RXFLUSH (0x0D)
#define MRF24J40_REG_ORDER (0x10)
#define MRF24J40_REG_TXMCR (0x11)
#define MRF24J40_REG_ACKTMOUT (0x12)
#define MRF24J40_REG_ESLOTG1 (0x13)
#define MRF24J40_REG_SYMTICKL (0x14)
#define MRF24J40_REG_SYMTICKH (0x15)
#define MRF24J40_REG_PACON0 (0x16)
#define MRF24J40_REG_PACON1 (0x17)
#define MRF24J40_REG_PACON2 (0x18)
#define MRF24J40_REG_TXBCON0 (0x1A)
#define MRF24J40_REG_TXNCON (0x1B)
#define MRF24J40_REG_TXG1CON (0x1C)
#define MRF24J40_REG_TXG2CON (0x1D)
#define MRF24J40_REG_ESLOTG23 (0x1E)
#define MRF24J40_REG_ESLOTG45 (0x1F)
#define MRF24J40_REG_ESLOTG67 (0x20)
#define MRF24J40_REG_TXPEND (0x21)
#define MRF24J40_REG_WAKECON (0x22)
#define MRF24J40_REG_FRMOFFSET (0x23)
#define MRF24J40_REG_TXSTAT (0x24)
#define MRF24J40_REG_TXBCON1 (0x25)
#define MRF24J40_REG_GATECLK (0x26)
#define MRF24J40_REG_TXTIME (0x27)
#define MRF24J40_REG_HSYMTMRL (0x28)
#define MRF24J40_REG_HSYMTMRH (0x29)
#define MRF24J40_REG_SOFTRST (0x2A)
#define MRF24J40_REG_SECCON0 (0x2C)
#define MRF24J40_REG_SECCON1 (0x2D)
#define MRF24J40_REG_TXSTBL (0x2E)
#define MRF24J40_REG_RXSR (0x30)
#define MRF24J40_REG_INTSTAT (0x31)
#define MRF24J40_REG_INTCON (0x32)
#define MRF24J40_REG_GPIO (0x33)
#define MRF24J40_REG_TRISGPIO (0x34)
#define MRF24J40_REG_SLPACK (0x35)
#define MRF24J40_REG_RFCTL (0x36)
#define MRF24J40_REG_SECCR2 (0x37)
#define MRF24J40_REG_BBREG0 (0x38)
#define MRF24J40_REG_BBREG1 (0x39)
#define MRF24J40_REG_BBREG2 (0x3A)
#define MRF24J40_REG_BBREG3 (0x3B)
#define MRF24J40_REG_BBREG4 (0x3C)
#define MRF24J40_REG_BBREG6 (0x3E)
#define MRF24J40_REG_CCAEDTH (0x3F)
/** @} */
/**
* @brief Long-Register addresses
* @{
*/
#define MRF24J40_REG_RFCON0 (0x200)
#define MRF24J40_REG_RFCON1 (0x201)
#define MRF24J40_REG_RFCON2 (0x202)
#define MRF24J40_REG_RFCON3 (0x203)
#define MRF24J40_REG_RFCON5 (0x205)
#define MRF24J40_REG_RFCON6 (0x206)
#define MRF24J40_REG_RFCON7 (0x207)
#define MRF24J40_REG_RFCON8 (0x208)
#define MRF24J40_REG_SLPCAL0 (0x209)
#define MRF24J40_REG_SLPCAL1 (0x20A)
#define MRF24J40_REG_SLPCAL2 (0x20B)
#define MRF24J40_REG_RFSTATE (0x20F)
#define MRF24J40_REG_RSSI (0x210)
#define MRF24J40_REG_SLPCON0 (0x211)
#define MRF24J40_REG_SLPCON1 (0x220)
#define MRF24J40_REG_WAKETIMEL (0x222)
#define MRF24J40_REG_WAKETIMEH (0x223)
#define MRF24J40_REG_REMCNTL (0x224)
#define MRF24J40_REG_REMCNTH (0x225)
#define MRF24J40_REG_MAINCNT0 (0x226)
#define MRF24J40_REG_MAINCNT1 (0x227)
#define MRF24J40_REG_MAINCNT2 (0x228)
#define MRF24J40_REG_MAINCNT3 (0x229)
#define MRF24J40_REG_TESTMODE (0x22F)
#define MRF24J40_REG_ASSOEADR0 (0x230)
#define MRF24J40_REG_ASSOEADR1 (0x231)
#define MRF24J40_REG_ASSOEADR2 (0x232)
#define MRF24J40_REG_ASSOEADR3 (0x233)
#define MRF24J40_REG_ASSOEADR4 (0x234)
#define MRF24J40_REG_ASSOEADR5 (0x235)
#define MRF24J40_REG_ASSOEADR6 (0x236)
#define MRF24J40_REG_ASSOEADR7 (0x237)
#define MRF24J40_REG_ASSOSADR0 (0x238)
#define MRF24J40_REG_ASSOSADR1 (0x239)
#define MRF24J40_REG_UPNONCE0 (0x240)
#define MRF24J40_REG_UPNONCE1 (0x241)
#define MRF24J40_REG_UPNONCE2 (0x242)
#define MRF24J40_REG_UPNONCE3 (0x243)
#define MRF24J40_REG_UPNONCE4 (0x244)
#define MRF24J40_REG_UPNONCE5 (0x245)
#define MRF24J40_REG_UPNONCE6 (0x246)
#define MRF24J40_REG_UPNONCE7 (0x247)
#define MRF24J40_REG_UPNONCE8 (0x248)
#define MRF24J40_REG_UPNONCE9 (0x249)
#define MRF24J40_REG_UPNONCE10 (0x24A)
#define MRF24J40_REG_UPNONCE11 (0x24B)
#define MRF24J40_REG_UPNONCE12 (0x24C)
/** @} */
/**
* @brief Timing definition for the mrf24j40.
* @{
*/
#define MRF24J40_RESET_DELAY (2000U) /* Datasheet MRF24J40 ~2ms */
#define MRF24J40_RESET_PULSE_WIDTH (20000U) /* 20ms (estimated */
#define MRF24J40_WAKEUP_DELAY (2000U)
/** Undocumented delay. Probably needed because the bit has to be sampled by the low speed sleep clock */
#define MRF24J40_DELAY_SLEEP_TOGGLE (50U)
#define MRF24J40_STATE_RESET_DELAY (200U)
/** @} */
/**
* @brief Bitfield definitions for the RXMCR register (0x00)
* @{
*/
#define MRF24J40_RXMCR_NOACKRSP (0b00100000)
#define MRF24J40_RXMCR_PANCOORD (0b00001000)
#define MRF24J40_RXMCR_COORD (0b00000100)
#define MRF24J40_RXMCR_ERRPKT (0b00000010)
#define MRF24J40_RXMCR_PROMI (0b00000001)
/** @} */
/**
* @brief Bitfield definitions for the RXFLUSH register (0x0D)
* @{
*/
#define MRF24J40_RXFLUSH_WAKEPOL (0b01000000)
#define MRF24J40_RXFLUSH_WAKEPAD (0b00100000)
#define MRF24J40_RXFLUSH_CMDONLY (0b00001000)
#define MRF24J40_RXFLUSH_DATAONLY (0b00000100)
#define MRF24J40_RXFLUSH_BCNONLY (0b00000010)
#define MRF24J40_RXFLUSH_RXFLUSH (0b00000001)
/** @} */
/**
* @brief Bitfield definitions for the TXMCR register (0x11)
* @{
*/
#define MRF24J40_TXMCR_CSMA_BACKOFF_MASK (0x07)
#define MRF24J40_TXMCR_MACMINBE (0b00011000)
#define MRF24J40_TXMCR_NOCSMA (0b10000000)
#define MRF24J40_TXMCR_BATLIFEXT (0b01000000)
#define MRF24J40_TXMCR_SLOTTED (0b00100000)
#define MRF24J40_TXMCR_MACMINBE1 (0b00010000)
#define MRF24J40_TXMCR_MACMINBE0 (0b00001000)
#define MRF24J40_TXMCR_CSMABF2 (0b00000100)
#define MRF24J40_TXMCR_CSMABF1 (0b00000010)
#define MRF24J40_TXMCR_CSMABF0 (0b00000001)
/** @} */
/**
* @brief Bitfield definitions for the PACON2 register (0x18)
* @{
*/
#define MRF24J40_PACON2_FIFOEN (0b10000000)
#define MRF24J40_PACON2_TXONTS3 (0b00100000)
#define MRF24J40_PACON2_TXONTS2 (0b00010000)
#define MRF24J40_PACON2_TXONTS1 (0b00001000)
#define MRF24J40_PACON2_TXONTS0 (0b00000100)
#define MRF24J40_PACON2_TXONT8 (0b00000010)
#define MRF24J40_PACON2_TXONT7 (0b00000001)
/** @} */
/**
* @brief Bitfield definitions for the TXNCON register (0x1B)
* @{
*/
#define MRF24J40_TXNCON_FPSTAT (0x10)
#define MRF24J40_TXNCON_INDIRECT (0x08)
#define MRF24J40_TXNCON_TXNACKREQ (0x04)
#define MRF24J40_TXNCON_TXNSECEN (0x02)
#define MRF24J40_TXNCON_TXNTRIG (0x01)
/** @} */
/**
* @brief Bitfield definitions for the WAKECON register (0x22)
* @{
*/
#define MRF24J40_WAKECON_IMMWAKE (0b10000000)
#define MRF24J40_WAKECON_REGWAKE (0b01000000)
/** @} */
/**
* @brief Bitfield definitions for the TXSTAT register (0x24)
* @{
*/
#define MRF24J40_TXSTAT_MAX_FRAME_RETRIES (0b11000000)
#define MRF24J40_TXSTAT_TXNRETRY1 (0b10000000)
#define MRF24J40_TXSTAT_TXNRETRY0 (0b01000000)
#define MRF24J40_TXSTAT_CCAFAIL (0b00100000)
#define MRF24J40_TXSTAT_TXG2FNT (0b00010000)
#define MRF24J40_TXSTAT_TXG1FNT (0b00001000)
#define MRF24J40_TXSTAT_TXG2STAT (0b00000100)
#define MRF24J40_TXSTAT_TXG1STAT (0b00000010)
#define MRF24J40_TXSTAT_TXNSTAT (0b00000001)
/** @} */
/**
* @brief Bitfield definitions for the SOFTRST register (0x2A)
* @{
*/
#define MRF24J40_SOFTRST_RSTPWR (0b00000100)
#define MRF24J40_SOFTRST_RSTBB (0b00000010)
#define MRF24J40_SOFTRST_RSTMAC (0b00000001)
/** @} */
/**
* @brief Bitfield definitions for the TXSTBL register (0x2E)
* @{
*/
#define MRF24J40_TXSTBL_RFSTBL3 (0x80)
#define MRF24J40_TXSTBL_RFSTBL2 (0x40)
#define MRF24J40_TXSTBL_RFSTBL1 (0x20)
#define MRF24J40_TXSTBL_RFSTBL0 (0x10)
#define MRF24J40_TXSTBL_MSIFS3 (0x08)
#define MRF24J40_TXSTBL_MSIFS2 (0x04)
#define MRF24J40_TXSTBL_MSIFS1 (0x02)
#define MRF24J40_TXSTBL_MSIFS0 (0x01)
/** @} */
/**
* @brief Bitfield definitions for the INTSTAT register (0x31)
* @{
*/
#define MRF24J40_INTSTAT_SLPIF (0x80)
#define MRF24J40_INTSTAT_WAKEIF (0x40)
#define MRF24J40_INTSTAT_HSYMTMRIF (0x20)
#define MRF24J40_INTSTAT_SECIF (0x10)
#define MRF24J40_INTSTAT_RXIF (0x08)
#define MRF24J40_INTSTAT_TXG2IF (0x04)
#define MRF24J40_INTSTAT_TXG1IF (0x02)
#define MRF24J40_INTSTAT_TXNIF (0x01)
/** @} */
/**
* @brief Bitfield definitions for the INTCON register (0x32)
* @{
*/
#define MRF24J40_INTCON_SLPIE (0x80)
#define MRF24J40_INTCON_WAKEIE (0x40)
#define MRF24J40_INTCON_HSYMTMRIE (0x20)
#define MRF24J40_INTCON_SECIE (0x10)
#define MRF24J40_INTCON_RXIE (0x08)
#define MRF24J40_INTCON_TXG2IE (0x04)
#define MRF24J40_INTCON_TXG1IE (0x02)
#define MRF24J40_INTCON_TXNIE (0x01)
/** @} */
/**
* @brief Bitfield definitions for the SLPACK register (0x35)
* @{
*/
#define MRF24J40_SLPACK_SLPACK (0b10000000)
/** @} */
/**
* @brief Bitfield definitions for the RFCTL register (0x36)
* @{
*/
#define MRF24J40_RFCTL_WAKECNT8 (0x10)
#define MRF24J40_RFCTL_WAKECNT7 (0x08)
#define MRF24J40_RFCTL_RFRST (0x04)
#define MRF24J40_RFCTL_RFTXMODE (0x02)
#define MRF24J40_RFCTL_RFRXMODE (0x01)
/** @} */
/**
* @brief Bitfield definitions for the BBREG1 register (0x39)
* @{
*/
#define MRF24J40_BBREG1_RXDECINV (0b00000100)
/** @} */
/**
* @brief Bitfield definitions for the BBREG2 register (0x3A)
* @{
*/
#define MRF24J40_BBREG2_CCAMODE3 (0b11000000)
#define MRF25J40_BBREG2_CCAMODE1 (0b10000000)
#define MRF24J40_BBREG2_CCAMODE2 (0b01000000)
#define MRF24J40_BBREG2_CCACSTH (0b00111100)
/** @} */
/**
* @brief Bitfield definitions for the BBREG6 register (0x3E)
* @{
*/
#define MRF24J40_BBREG6_RSSIMODE1 (0b10000000)
#define MRF24J40_BBREG6_RSSIMODE2 (0b01000000)
#define MRF24J40_BBREG2_RSSIRDY (0b00000001)
#define MRF24J40_BBREG2_CCACSTH (0b00111100)
/** @} */
/**
* @brief Bitfield definitions for the RFCON1 register (0x201)
* @{
*/
#define MRF24J40_RFCON1_VCOOPT7 (0x80)
#define MRF24J40_RFCON1_VCOOPT6 (0x40)
#define MRF24J40_RFCON1_VCOOPT5 (0x20)
#define MRF24J40_RFCON1_VCOOPT4 (0x10)
#define MRF24J40_RFCON1_VCOOPT3 (0x08)
#define MRF24J40_RFCON1_VCOOPT2 (0x04)
#define MRF24J40_RFCON1_VCOOPT1 (0x02)
#define MRF24J40_RFCON1_VCOOPT0 (0x01)
/** @} */
/**
* @brief Bitfield definitions for the RFCON2 register (0x202)
* @{
*/
#define MRF24J40_RFCON2_PLLEN (0x80)
/** @} */
/**
* @brief Bitfield definitions for the RFCON6 register (0x206)
* @{
*/
#define MRF24J40_RFCON6_TXFIL (0x80)
#define MRF24J40_RFCON6_20MRECVR (0x10)
#define MRF24J40_RFCON6_BATEN (0x08)
/** @} */
/**
* @brief Bitfield definitions for the RFCON7 register (0x207)
* @{
*/
#define MRF24J40_RFCON7_SLPCLKSEL1 (0x80)
#define MRF24J40_RFCON7_SLPCLKSEL2 (0x40)
/** @} */
/**
* @brief Bitfield definitions for the RFCON8 register (0x208)
* @{
*/
#define MRF24J40_RFCON8_RFVCO (0x10)
/** @} */
/**
* @brief Bitfield definitions for the RFSTATE register (0x20F)
* @{
*/
#define MRF24J40_RFSTATE_MASK (0xA0)
#define MRF24J40_RFSTATE_RTSEL2 (0xE0)
#define MRF24J40_RFSTATE_RTSEL1 (0xC0)
#define MRF24J40_RFSTATE_RX (0xA0)
#define MRF24J40_RFSTATE_TX (0x80)
#define MRF24J40_RFSTATE_CALVCO (0x60)
#define MRF24J40_RFSTATE_SLEEP (0x40)
#define MRF24J40_RFSTATE_CALFIL (0x20)
#define MRF24J40_RFSTATE_RESET (0x00)
/** @} */
/**
* @brief Bitfield definitions for the SLPCON1 register (0x211)
* @{
*/
#define MRF24J40_SLPCON0_INTEDGE (0x02)
#define MRF24J40_SLPCON0_SLPCLKEN (0x01)
/** @} */
/**
* @brief Bitfield definitions for the SLPCON1 register (0x212)
* @{
*/
#define MRF24J40_SLPCON1_CLKOUTEN (0x20)
#define MRF24J40_SLPCON1_SLPCLKDIV4 (0x10)
#define MRF24J40_SLPCON1_SLPCLKDIV3 (0x08)
#define MRF24J40_SLPCON1_SLPCLKDIV2 (0x04)
#define MRF24J40_SLPCON1_SLPCLKDIV1 (0x02)
#define MRF24J40_SLPCON1_SLPCLKDIV0 (0x01)
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* MRF24J40_REGISTERS_H */
/** @} */

168
drivers/mrf24j40/mrf24j40.c

@ -0,0 +1,168 @@
/*
* Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
* Copyright (C) 2017 Koen Zandberg <koen@bergzand.net>
*
* 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_mrf24j40
* @{
*
* @file
* @brief Implementation of public functions for MRF24J40 drivers
*
* @author Koen Zandberg <koen@bergzand.net>
* @author Neo Nenaco <neo@nenaco.de>
*
* @}
*/
#include "uuid.h"
#include "byteorder.h"
#include "net/gnrc.h"
#include "mrf24j40_registers.h"
#include "mrf24j40_internal.h"
#include "mrf24j40_netdev.h"
#include "xtimer.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
void mrf24j40_setup(mrf24j40_t *dev, const mrf24j40_params_t *params)
{
netdev2_t *netdev = (netdev2_t *)dev;
netdev->driver = &mrf24j40_driver;
/* initialize device descriptor */
memcpy(&dev->params, params, sizeof(mrf24j40_params_t));
}
void mrf24j40_reset(mrf24j40_t *dev)
{
eui64_t addr_long;
mrf24j40_init(dev);
/* reset options and sequence number */
dev->netdev.seq = 0;
dev->netdev.flags = 0;
/* get an 8-byte unique ID to use as hardware address */
uuid_get(addr_long.uint8, IEEE802154_LONG_ADDRESS_LEN);
addr_long.uint8[0] &= ~(0x01);
addr_long.uint8[0] |= (0x02);
/* set short and long address */
mrf24j40_set_addr_long(dev, NTOHLL(addr_long.uint64.u64));
mrf24j40_set_addr_short(dev, NTOHS(addr_long.uint16[0].u16));
/* set default PAN id */
mrf24j40_set_pan(dev, IEEE802154_DEFAULT_PANID);
mrf24j40_set_chan(dev, IEEE802154_DEFAULT_CHANNEL);
/* configure Immediate Sleep and Wake-Up mode */
mrf24j40_reg_write_short(dev, MRF24J40_REG_WAKECON, MRF24J40_WAKECON_IMMWAKE);
/* set default options */
mrf24j40_set_option(dev, IEEE802154_FCF_PAN_COMP, true);
mrf24j40_set_option(dev, NETDEV2_IEEE802154_SRC_MODE_LONG, true);
mrf24j40_set_option(dev, NETDEV2_IEEE802154_ACK_REQ, true);
mrf24j40_set_option(dev, MRF24J40_OPT_CSMA, true);
mrf24j40_set_option(dev, MRF24J40_OPT_TELL_RX_START, false);
mrf24j40_set_option(dev, MRF24J40_OPT_TELL_RX_END, true);
#ifdef MODULE_NETSTATS_L2
mrf24j40_set_option(dev, MRF24J40_OPT_TELL_TX_END, true);
#endif
/* set default protocol */
#ifdef MODULE_GNRC_SIXLOWPAN
dev->netdev.proto = GNRC_NETTYPE_SIXLOWPAN;
#elif MODULE_GNRC
dev->netdev.proto = GNRC_NETTYPE_UNDEF;
#endif
/* go into RX state */
mrf24j40_reset_tasks(dev);
dev->state = 0;
mrf24j40_set_state(dev, MRF24J40_PSEUDO_STATE_IDLE);
DEBUG("mrf24j40_reset(): reset complete.\n");
}
bool mrf24j40_cca(mrf24j40_t *dev)
{
uint8_t tmp_ccaedth;
uint8_t status;
uint8_t tmp_rssi;
mrf24j40_assert_awake(dev);
/* trigger CCA measurment */
/* take a look onto datasheet chapter 3.6.1 */
mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG6, MRF24J40_BBREG6_RSSIMODE1);
/* wait for result to be ready */
do {
status = mrf24j40_reg_read_short(dev, MRF24J40_REG_BBREG6);
} while (!(status & MRF24J40_BBREG2_RSSIRDY));
mrf24j40_assert_sleep(dev);
/* return according to measurement */
tmp_ccaedth = mrf24j40_reg_read_short(dev, MRF24J40_REG_CCAEDTH); /* Energy detection threshold */
tmp_rssi = mrf24j40_reg_read_long(dev, MRF24J40_REG_RSSI);
if (tmp_rssi < tmp_ccaedth) {
/* channel is clear */
return true; /* idle */
}
else {
/* channel is busy */
return false;
}
}
void mrf24j40_tx_prepare(mrf24j40_t *dev)
{
DEBUG("[mrf24j40] TX_Prepare, Current state: %x\n", dev->state);
do {
mrf24j40_update_tasks(dev);
} while (!(dev->pending & MRF24J40_TASK_TX_DONE));
mrf24j40_assert_awake(dev);
dev->pending &= ~(MRF24J40_TASK_TX_DONE);
dev->tx_frame_len = IEEE802154_FCS_LEN;
}
size_t mrf24j40_tx_load(mrf24j40_t *dev, uint8_t *data, size_t len, size_t offset)
{
DEBUG("[mrf24j40] TX_load, Current state: %x\n", dev->state);
dev->tx_frame_len += (uint8_t)len;
mrf24j40_tx_normal_fifo_write(dev, MRF24J40_TX_NORMAL_FIFO + offset + 2, data, len);
return offset + len;
}
void mrf24j40_tx_exec(mrf24j40_t *dev)
{
netdev2_t *netdev = (netdev2_t *)dev;
dev->tx_frame_len = dev->tx_frame_len - IEEE802154_FCS_LEN;
/* write frame length field in FIFO */
mrf24j40_tx_normal_fifo_write(dev, MRF24J40_TX_NORMAL_FIFO + 1, &(dev->tx_frame_len), 1);
/* write header length to FIFO address 0x00 */
/* from figure 3-11 datasheet: header length = 2 Bytes Frame Control
* + 1 Byte Seq. No.
* + 4 to 20 Bytes Addressing Fields
*/
mrf24j40_reg_write_long(dev, MRF24J40_TX_NORMAL_FIFO, dev->header_len);
if (dev->netdev.flags & NETDEV2_IEEE802154_ACK_REQ) {
mrf24j40_reg_write_short(dev, MRF24J40_REG_TXNCON, MRF24J40_TXNCON_TXNACKREQ | MRF24J40_TXNCON_TXNTRIG);
}
else {
mrf24j40_reg_write_short(dev, MRF24J40_REG_TXNCON, MRF24J40_TXNCON_TXNTRIG);
}
if (netdev->event_callback && (dev->netdev.flags & MRF24J40_OPT_TELL_TX_START)) {
netdev->event_callback(netdev, NETDEV2_EVENT_TX_STARTED);
}
}

490
drivers/mrf24j40/mrf24j40_getset.c

@ -0,0 +1,490 @@
/*
* Copyright (C) 2017 Neo Nenaco <neo@nenaco.de>
* Copyright (C) 2016 Koen Zandberg <koen@bergzand.net>
*
* 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_mrf24j40
* @{
*
* @file
* @brief Getter and setter functions for the MRF24J40 drivers
*
* @author Koen Zandberg <koen@bergzand.net>
* @author Neo Nenaco <neo@nenaco.de>
*
* @}
*/
#include "mrf24j40.h"
#include "mrf24j40_internal.h"
#include "mrf24j40_registers.h"
#include "xtimer.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
/* Values of RFCON3 - Address: 0x203
* 0b00000000 -> 0dB -> 0
* 0b00001000 -> -0.5dB -> 0
* 0b00010000 -> -1.2dB -> -1
* 0b00011000 -> -1.9dB -> -2
* 0b00100000 -> -2.8dB -> -3
* 0b00101000 -> -3.7dB -> -4
* 0b00110000 -> -4.9dB -> -5
* 0b00111000 -> -6.3dB -> -6
* 0b01000000 -> -10dB -> -10
* 0b01001000 -> -10.5dB-> -10
* 0b01010000 -> -11.2dB-> -11
* 0b01011000 -> -11.9dB-> -12
* 0b01100000 -> -12.8dB-> -13
* 0b01101000 -> -13.7dB-> -14
* 0b01110000 -> -14.9dB-> -15
* 0b01111000 -> -16.3dB-> -16
* 0b10000000 -> -20dB -> -20
* 0b10001000 -> -20.5dB-> -20
* 0b10010000 -> -21.2dB-> -21
* 0b10011000 -> -21.9dB-> -22
* 0b10100000 -> -22.8dB-> -23
* 0b10101000 -> -23.7dB-> -24
* 0b10110000 -> -24.9dB-> -25
* 0b10111000 -> -26.3dB-> -26
* 0b11000000 -> -30dB -> -30
* 0b11001000 -> -30.5dB-> -30
* 0b11010000 -> -31.2dB-> -31
* 0b11011000 -> -31.9dB-> -32
* 0b11100000 -> -32.8dB-> -33
* 0b11101000 -> -33.7dB-> -34
* 0b11110000 -> -34.9dB-> -35
* 0b11111000 -> -36.3dB-> -36
*/
static const int16_t tx_pow_to_dbm[] = { 0, 0, -1, -2, -3, -4, -5, -6,
-10, -10, -11, -12, -13, -14, -15, -16,
-20, -20, -21, -22, -23, -24, -25, -26,
-30, -30, -31, -32, -33, -34, -35, -36 };
static const uint8_t dbm_to_tx_pow[] = { 0x00, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x38, 0x38, 0x40,
0x40, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78, 0x78, 0x78, 0x80,
0x80, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xb8, 0xb8, 0xc0,
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, \