
15 changed files with 2724 additions and 0 deletions
@ -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 */ |
||||
/** @} */ |
@ -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 */ |
||||
/** @} */ |
@ -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 */ |
||||
/** @} */ |
@ -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 */ |
||||
/** @} */ |
@ -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 */ |
||||
/** @} */ |
@ -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); |
||||
} |
||||
} |
@ -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, \
|
||||