1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/drivers/include/mrf24j40.h

409 lines
12 KiB
C

/*
* 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
*
* This module contains drivers for radio devices in Microchip MRF24J40 series.
* The driver is aimed to work with all devices of this series.
*
* @warning This driver doesn't handle the wake pin. As of now, it is
* required that the wake pin is high prior to the initialization
* (e.g. by connecting it to VCC in the board design).
* @note A PR extending @ref mrf24j40_params_t to contain the wake pin
* and adding appropriate handling of the wake pin to the driver
* logic would be a welcome addition.
*
* Default TX power is 0dBm.
*
* TX power mapping:
* * 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
*
* @{
*
* @file
* @brief Interface definition for MRF24J40 based drivers
* @anchor drivers_mrf24j40
*
* @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/netdev.h"
#include "net/netdev/ieee802154.h"
#include "net/gnrc/nettype.h"
#include "net/ieee802154/radio.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name 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 */
/** @} */
/**
* @name Internal device option flags
*
* `0x00ff` is reserved for general IEEE 802.15.4 flags
* (see @ref netdev_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_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) */
#define MRF24J40_MAX_MINBE (3U) /**< Maximum value of minimum
exponential backoff */
#define MRF24J40_MIN_TXPOWER (-36) /**< Minimum transmission power (dBm) */
#define MRF24J40_MAX_TXPOWER (0) /**< Maximum transmission power (dBm) */
/**
* @defgroup drivers_mrf24j40_config mrf24j40 driver compile configuration
* @ingroup drivers_mrf24j40
* @ingroup config_drivers_netdev
* @{
*/
/**
* @brief Enable external PA/LNA control
*
* Set to 1 to increase RSSI for MRF24J40MC/MD/ME devices. No effect on
* MRF24J40MA. For more information, please refer to section 4.2 of MRF24J40
* datasheet.
*/
#if defined(DOXYGEN)
#define CONFIG_MRF24J40_USE_EXT_PA_LNA
#endif
/**
* @brief Enable basic self-test on init
*
* Perform a write / read to a known register on startup to detect
* if the device is connected.
* Set this to 1 if you want the boot not to hang if the device is
* not connected / there are SPI errors.
*/
#if defined(DOXYGEN)
#define CONFIG_MRF24J40_TEST_SPI_CONNECTION
#endif
/** @} */
/**
* @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 {
/* device specific fields */
const mrf24j40_params_t *params; /**< parameters for initialization */
uint8_t fcf_low; /**< Low 8 FCF bits of the current TX frame. */
uint8_t pending; /**< Flags for pending tasks */
bool tx_pending; /**< Whether a transmission is pending or not */
} mrf24j40_t;
/**
* @brief Trigger a hardware reset and configure radio with default values
*
* @param[in] dev device to reset
*
* @return 0 on success, error otherwise
*/
int mrf24j40_reset(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 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, const uint8_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 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 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 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 Enable or disable proprietary Turbo Mode.
*
* Turbo mode is only compatible with other mrf24j40 chips.
*
* turbo off: 250 kbit/s (IEEE mode)
* turbo on: 625 kbit/s
*
* @param[in] dev device to change state of
* @param[in] enable turbo mode control
*/
void mrf24j40_set_turbo(mrf24j40_t *dev, bool enable);
/**
* @brief Put in sleep mode
*
* @param[in] dev device to put to sleep
*/
void mrf24j40_sleep(mrf24j40_t *dev);
/**
* @brief Wake up from sleep mode
*
* @param[in] dev device to eventually wake up
*/
void mrf24j40_wake_up(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 Convert scalar from mrf24j40 RSSI to dBm
*
* @param[in] value value to convert to dBm
* @return converted value in dBm
*/
int8_t mrf24j40_dbm_from_reg(uint8_t value);
/**
* @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);
/**
* @brief IRQ Handler for the MRF24J40 device
*
* @param[in] dev pointer to the IEEE 802.15.4 Radio HAL descriptor
*/
void mrf24j40_radio_irq_handler(void *dev);
/**
* @brief Initialize the given MRF24J40 device
* @param[out] dev device descriptor
* @param[in] params parameters for device initialization
* @param[in] hal pointer to IEEE 802.15.4 Radio HAL descriptor
* @param[in] cb ISR callback
* @param[in] ctx context pointer handed to isr
*
* @return 0 on success
* @return <0 on error
*/
int mrf24j40_init(mrf24j40_t *dev, const mrf24j40_params_t *params, ieee802154_dev_t *hal,
gpio_cb_t cb, void *ctx);
#ifdef __cplusplus
}
#endif
#endif /* MRF24J40_H */
/** @} */