1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/drivers/include/at86rf215.h
Karl Fessel 05f114d0af doc: fix unbalaced grouping
- most were trivial
    - missing group close or open
    - extra space
    - no doxygen comment
- name commad might open an implicit group
    this hould also be implicit cosed but does not happen somtimes
- crazy: internal declared groups have to be closed internal
2022-09-14 15:05:25 +02:00

687 lines
21 KiB
C

/*
* Copyright (C) 2019 2019 ML!PA Consulting GmbH
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @defgroup drivers_at86rf215 AT86RF215 based drivers
* @ingroup drivers_netdev
*
* This module contains a driver for the Atmel AT86RF215 radio.
*
* @{
*
* @file
* @brief Interface definition for AT86RF215 based drivers
*
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
*/
#ifndef AT86RF215_H
#define AT86RF215_H
#include <stdint.h>
#include <stdbool.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 "xtimer.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Registers for the Radio Frontend
*/
typedef struct at86rf215_RF_regs at86rf215_RF_regs_t;
/**
* @brief Registers for the BaseBand Controller
*/
typedef struct at86rf215_BBC_regs at86rf215_BBC_regs_t;
/**
* @brief Signature for the Battery monitor callback.
*
* @param[in] arg optional argument which is passed to the
* callback
*/
typedef void (*at86rf215_batmon_cb_t)(void *arg);
/**
* @brief MR-O-QPSK chip rates (kChip/s)
*/
enum {
AT86RF215_FCHIP_100,
AT86RF215_FCHIP_200,
AT86RF215_FCHIP_1000,
AT86RF215_FCHIP_2000,
};
/**
* @brief Maximum possible packet size in byte
*/
#define AT86RF215_MAX_PKT_LENGTH (2047)
/**
* @defgroup drivers_at86rf215_config AT86RF215 driver compile configuration
* @ingroup config_drivers_netdev
* @{
*/
/**
* @brief Set to 1 if the clock output of the AT86RF215 is used
* as a clock source on the board.
* Otherwise it is turned off to save energy.
*/
#ifdef DOXYGEN
#define CONFIG_AT86RF215_USE_CLOCK_OUTPUT
#endif
#if defined(DOXYGEN) && !defined(CONFIG_AT86RF215_TRIM_VAL)
/**
* @brief Trim value for the external crystal oscillator.
*
* Each increment adds 300nF capacitance between the crystal oscillator pins
* TCXO and XTAL2.
*
* Range: 0..15
*
* Use in conjunction with @see CONFIG_AT86RF215_USE_CLOCK_OUTPUT and a frequency
* meter connected to the clock output pin of the AT86RF215.
* Tweak the value until the measured clock output matches 26 MHz the best.
*/
#define CONFIG_AT86RF215_TRIM_VAL (0)
#endif
/**
* @name Channel configuration
* @{
*/
#ifndef CONFIG_AT86RF215_DEFAULT_CHANNEL
#define CONFIG_AT86RF215_DEFAULT_CHANNEL (CONFIG_IEEE802154_DEFAULT_CHANNEL)
#endif
#ifndef CONFIG_AT86RF215_DEFAULT_SUBGHZ_CHANNEL
#define CONFIG_AT86RF215_DEFAULT_SUBGHZ_CHANNEL (CONFIG_IEEE802154_DEFAULT_SUBGHZ_CHANNEL)
#endif
/** @} */
/**
* @name Enable Reduced Power Consumption
* @{
*/
#ifndef CONFIG_AT86RF215_RPC_EN
#define CONFIG_AT86RF215_RPC_EN (0)
#endif
/** @} */
/**
* @name Default Battery Monitor trigger threshold (in mV)
* if battery monitoring is enabled
* @{
*/
#ifndef CONFIG_AT86RF215_BATMON_THRESHOLD
#define CONFIG_AT86RF215_BATMON_THRESHOLD (1800)
#endif
/** @} */
/**
* @name Default PHY Mode
* @{
*/
#if IS_ACTIVE(CONFIG_AT86RF215_DEFAULT_LEGACY_OQPSK)
#define CONFIG_AT86RF215_DEFAULT_PHY_MODE (IEEE802154_PHY_OQPSK)
#elif IS_ACTIVE(CONFIG_AT86RF215_DEFAULT_MR_OQPSK)
#define CONFIG_AT86RF215_DEFAULT_PHY_MODE (IEEE802154_PHY_MR_OQPSK)
#elif IS_ACTIVE(CONFIG_AT86RF215_DEFAULT_MR_OFDM)
#define CONFIG_AT86RF215_DEFAULT_PHY_MODE (IEEE802154_PHY_MR_OFDM)
#endif
#ifndef CONFIG_AT86RF215_DEFAULT_PHY_MODE
#define CONFIG_AT86RF215_DEFAULT_PHY_MODE (IEEE802154_PHY_OQPSK)
#endif
/** @} */
/**
* @name Default O-QPSK Rate Mode
* Non-zero value enables proprietary high data rate by default
* @{
*/
#ifndef CONFIG_AT86RF215_DEFAULT_OQPSK_RATE
#define CONFIG_AT86RF215_DEFAULT_OQPSK_RATE (0)
#endif
/** @} */
/**
* @name Default MR-O-QPSK Chip Rate
* @{
*/
#if IS_ACTIVE(CONFIG_AT86RF215_DEFAULT_MR_OQPSK_CHIPS_100)
#define CONFIG_AT86RF215_DEFAULT_MR_OQPSK_CHIPS (AT86RF215_FCHIP_100)
#elif IS_ACTIVE(CONFIG_AT86RF215_DEFAULT_MR_OQPSK_CHIPS_200)
#define CONFIG_AT86RF215_DEFAULT_MR_OQPSK_CHIPS (AT86RF215_FCHIP_200)
#elif IS_ACTIVE(CONFIG_AT86RF215_DEFAULT_MR_OQPSK_CHIPS_1000)
#define CONFIG_AT86RF215_DEFAULT_MR_OQPSK_CHIPS (AT86RF215_FCHIP_1000)
#elif IS_ACTIVE(CONFIG_AT86RF215_DEFAULT_MR_OQPSK_CHIPS_2000)
#define CONFIG_AT86RF215_DEFAULT_MR_OQPSK_CHIPS (AT86RF215_FCHIP_2000)
#endif
#ifndef CONFIG_AT86RF215_DEFAULT_MR_OQPSK_CHIPS
#define CONFIG_AT86RF215_DEFAULT_MR_OQPSK_CHIPS (AT86RF215_FCHIP_1000)
#endif
/** @} */
/**
* @name Default MR-O-QPSK Rate Mode
* @{
*/
#ifndef CONFIG_AT86RF215_DEFAULT_MR_OQPSK_RATE
#define CONFIG_AT86RF215_DEFAULT_MR_OQPSK_RATE (2)
#endif
/** @} */
/**
* @name Default MR-OFDM Option
* @{
*/
#ifndef CONFIG_AT86RF215_DEFAULT_MR_OFDM_OPT
#define CONFIG_AT86RF215_DEFAULT_MR_OFDM_OPT (2)
#endif
/** @} */
/**
* @name Default MR-OFDM Modulation & Coding Scheme
* @{
*/
#ifndef CONFIG_AT86RF215_DEFAULT_MR_OFDM_MCS
#define CONFIG_AT86RF215_DEFAULT_MR_OFDM_MCS (2)
#endif
/** @} */
/**
* @name Default MR-FSK Symbol Rate
* @{
*/
#ifndef CONFIG_AT86RF215_DEFAULT_MR_FSK_SRATE
#define CONFIG_AT86RF215_DEFAULT_MR_FSK_SRATE FSK_SRATE_200K
#endif
/** @} */
/**
* @name Default MR-FSK Modulation Index, fraction of 64
* @{
*/
#ifndef CONFIG_AT86RF215_DEFAULT_MR_FSK_MOD_IDX
#define CONFIG_AT86RF215_DEFAULT_MR_FSK_MOD_IDX (64)
#endif
/** @} */
/**
* @name Default MR-FSK Modulation Order
* @{
*/
#ifndef CONFIG_AT86RF215_DEFAULT_MR_FSK_MORD
#define CONFIG_AT86RF215_DEFAULT_MR_FSK_MORD FSK_MORD_4SFK
#endif
/** @} */
/**
* @name Default MR-FSK Forward Error Correction Scheme
* @{
*/
#ifndef CONFIG_AT86RF215_DEFAULT_MR_FSK_FEC
#define CONFIG_AT86RF215_DEFAULT_MR_FSK_FEC IEEE802154_FEC_NONE
#endif
/** @} */
/**
* @brief Default TX power (0dBm)
*/
#ifndef CONFIG_AT86RF215_DEFAULT_TXPOWER
#define CONFIG_AT86RF215_DEFAULT_TXPOWER (CONFIG_IEEE802154_DEFAULT_TXPOWER)
#endif
/** @} */
/**
* @name Flags for device internal states (see datasheet)
* @{
*/
typedef enum {
AT86RF215_STATE_OFF, /**< radio not configured */
AT86RF215_STATE_IDLE, /**< idle state, listening */
AT86RF215_STATE_RX_SEND_ACK,/**< receiving frame, sending ACK */
AT86RF215_STATE_TX, /**< sending frame */
AT86RF215_STATE_TX_WAIT_ACK,/**< sending frame, wait for ACK */
AT86RF215_STATE_SLEEP /**< sleep mode, not listening */
} at86rf215_state_t;
/** @} */
enum {
AT86RF215_MODE_LEGACY_OQPSK,
AT86RF215_MODE_MR_OQPSK,
AT86RF215_MODE_MR_OFDM,
AT86RF215_MODE_MR_FSK
};
/**
* @name Clock Output Driver Strength
* @{
*/
typedef enum {
AT86RF215_CLKO_2mA = 0 << 3, /**< 2 mA */
AT86RF215_CLKO_4mA = 1 << 3, /**< 4 mA */
AT86RF215_CLKO_6mA = 2 << 3, /**< 6 mA */
AT86RF215_CLKO_8mA = 3 << 3, /**< 8 mA */
} at86rf215_clko_cur_t;
/** @} */
/**
* @name Clock Output Frequency
* @{
*/
typedef enum {
AT86RF215_CLKO_OFF = 0, /**< Clock Output Disabled */
AT86RF215_CLKO_26_MHz, /**< 26 MHz */
AT86RF215_CLKO_32_MHz, /**< 32 MHz */
AT86RF215_CLKO_16_MHz, /**< 16 MHz */
AT86RF215_CLKO_8_MHz, /**< 8 MHz */
AT86RF215_CLKO_4_MHz, /**< 4 MHz */
AT86RF215_CLKO_2_MHz, /**< 2 MHz */
AT86RF215_CLKO_1_MHz, /**< 1 MHz */
} at86rf215_clko_freq_t;
/** @} */
/**
* @name Internal device option flags
* @{
*/
#define AT86RF215_OPT_CSMA (0x0010) /**< CSMA active */
#define AT86RF215_OPT_PROMISCUOUS (0x0020) /**< promiscuous mode active */
#define AT86RF215_OPT_PRELOADING (0x0040) /**< preloading enabled */
#define AT86RF215_OPT_AUTOACK (0x0080) /**< Auto ACK active */
#define AT86RF215_OPT_ACK_REQUESTED (0x0100) /**< ACK requested for current frame */
#define AT86RF215_OPT_AGCH (0x0200) /**< AGC Hold active */
#define AT86RF215_OPT_TX_PENDING (0x0400) /**< Frame is loaded into TX buffer */
#define AT86RF215_OPT_CCA_PENDING (0x0800) /**< CCA needs to be done for the current frame */
#define AT86RF215_OPT_RPC (0x1000) /**< Enable Reduced Power Consumption */
#define AT86RF215_OPT_CCATX (0x2000) /**< TX after CCA performd automatically */
/** @} */
/**
* @name Internal timeout flags
* @{
*/
#define AT86RF215_TIMEOUT_ACK (0x0001) /**< ACK timeout */
#define AT86RF215_TIMEOUT_CSMA (0x0002) /**< CMSA timeout */
/** @} */
/**
* @brief struct holding all params needed for device initialization
*/
typedef struct at86rf215_params {
spi_t spi; /**< SPI bus the device is connected to */
spi_clk_t spi_clk; /**< SPI clock 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 */
} at86rf215_params_t;
/**
* @brief Device descriptor for AT86RF215 radio devices
*
* @extends netdev_ieee802154_t
*/
typedef struct at86rf215 {
netdev_ieee802154_t netdev; /**< netdev parent struct */
/* device specific fields */
at86rf215_params_t params; /**< parameters for initialization */
struct at86rf215 *sibling; /**< The other radio */
const at86rf215_RF_regs_t *RF; /**< Radio Frontend Registers */
const at86rf215_BBC_regs_t *BBC; /**< Baseband Registers */
xtimer_t timer; /**< timer for ACK & CSMA timeout */
uint32_t ack_timeout_usec; /**< time to wait before retransmission in µs */
uint32_t csma_backoff_period; /**< CSMA Backoff period */
uint16_t flags; /**< Device specific flags */
uint16_t num_chans; /**< Number of legal channel at current modulation */
uint16_t tx_frame_len; /**< length of the current TX frame */
uint8_t timeout; /**< indicates which timeout was reached */
uint8_t state; /**< current state of the radio */
uint8_t retries_max; /**< number of retries until ACK is received */
uint8_t retries; /**< retries left */
uint8_t csma_retries_max; /**< number of retries until channel is clear */
uint8_t csma_retries; /**< CSMA retries left */
#ifdef MODULE_NETDEV_IEEE802154_MR_FSK
uint8_t fsk_pl; /**< FSK Preamble Length */
#endif
uint8_t csma_minbe; /**< CSMA minimum backoff exponent */
uint8_t csma_maxbe; /**< CSMA maximum backoff exponent */
int8_t csma_ed; /**< CSMA energy detect threshold */
} at86rf215_t;
/**
* @brief Setup an AT86RF215 based device state
*
* @param[out] dev_09 sub-GHz device descriptor
* @param[out] dev_24 2.4 GHz device descriptor
* @param[in] params parameters for device initialization
* @param[in] index index of @p params in a global parameter struct array.
* If initialized manually, pass a unique identifier instead.
*/
void at86rf215_setup(at86rf215_t *dev_09, at86rf215_t *dev_24, const at86rf215_params_t *params, uint8_t index);
/**
* @brief Trigger a hardware reset and configure radio with default values.
*
* @param[in,out] dev device to configure
*/
void at86rf215_reset_and_cfg(at86rf215_t *dev);
/**
* @brief Trigger a hardware reset, configuration is retained.
*
* @param[in,out] dev device to reset
*/
void at86rf215_reset(at86rf215_t *dev);
/**
* @brief Get the short address of the given device form multi address filter
*
* @param[in] dev device to read from
* @param[in] filter address filter to read
*
* @return the currently set (2-byte) short address
*/
uint16_t at86rf215_get_addr_short(const at86rf215_t *dev, uint8_t filter);
/**
* @brief Set the short address of the given device to multi address filter
*
* @param[in,out] dev device to write to
* @param[in] filter (1-byte) address filter to set
* @param[in] addr (2-byte) short address to set
*/
void at86rf215_set_addr_short(at86rf215_t *dev, uint8_t filter, uint16_t addr);
/**
* @brief Get whether a frame filter is enabled or not
*
* @param[in] dev device to read from
* @param[in] filter (1-byte) filter to get
*
* @return (bool) the current state of the filter
*/
bool at86rf215_get_framefilter_enabled(at86rf215_t *dev, uint8_t filter);
/**
* @brief Enables a frame filter
*
* @param[in] dev device to read from
* @param[in] filter (1-byte) filter to get
*
*/
void at86rf215_disable_framefilter(at86rf215_t *dev, uint8_t filter);
/**
* @brief Disables a frame filter
*
* @param[in] dev device to read from
* @param[in] filter (1-byte) filter to get
*
*/
void at86rf215_enable_framefilter(at86rf215_t *dev, uint8_t filter);
/**
* @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 at86rf215_get_addr_long(const at86rf215_t *dev);
/**
* @brief Set the long address of the given device
*
* @param[in,out] dev device to write to
* @param[in] addr (8-byte) long address to set
*/
void at86rf215_set_addr_long(at86rf215_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 at86rf215_get_chan(const at86rf215_t *dev);
/**
* @brief Set the channel number of the given device
*
* @param[in,out] dev device to write to
* @param[in] chan channel number to set
*/
void at86rf215_set_chan(at86rf215_t *dev, uint16_t chan);
/**
* @brief Get the configured PAN ID of the given device from multi address filter
*
* @param[in] dev device to read from
* @param[in] filter address filter to read from
*
* @return the currently set PAN ID
*/
uint16_t at86rf215_get_pan(const at86rf215_t *dev, uint8_t filter);
/**
* @brief Set the PAN ID of the given address filter
*
* @param[in,out] dev device to write to
* @param[in] filter address filter to set
* @param[in] pan PAN ID to set
*/
void at86rf215_set_pan(at86rf215_t *dev, uint8_t filter, 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 at86rf215_get_txpower(const at86rf215_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 at86rf215_set_txpower(const at86rf215_t *dev, int16_t txpower);
/**
* @brief Get the CCA threshold value
*
* @param[in] dev device to read value from
*
* @return the current CCA threshold value
*/
int8_t at86rf215_get_cca_threshold(const at86rf215_t *dev);
/**
* @brief Set the CCA threshold value
*
* @param[in] dev device to write to
* @param[in] value the new CCA threshold value
*/
void at86rf215_set_cca_threshold(at86rf215_t *dev, int8_t value);
/**
* @brief Get the latest ED level measurement
*
* @param[in] dev device to read value from
*
* @return the last ED level
*/
int8_t at86rf215_get_ed_level(at86rf215_t *dev);
/**
* @brief Enable or disable driver specific options
*
* @param[in,out] 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 at86rf215_set_option(at86rf215_t *dev, uint16_t option, bool state);
/**
* @brief Set crystal oscillator trim value.
*
* An internal capacitance array is connected to the
* crystal oscillator pins TCXO and XTAL2.
*
* Each increment of the trim value adds 0.3pF capacitance
* to the oscillator circuit.
*
* To trim a board, enable the clock output with
* @ref at86rf215_set_clock_output and connect a frequency
* counter to the clock output pin.
* Then adjust the trim value until it the measured frequency
* closely matches the configured output frequency.
*
* It is recommended to use a 26 MHz output frequency for the
* test as this is the raw frequency of the external oscillator.
*
* The resulting trim value must then be stored in a persistent
* memory area of the board to be set via @ref CONFIG_AT86RF215_TRIM_VAL
*
* @param[in] dev device to configure
* @param[in] trim trim value
*/
void at86rf215_set_trim(at86rf215_t *dev, uint8_t trim);
/**
* @brief Configure the Clock Output pin
*
* @param[in] dev device to configure
* @param[in] cur Clock output current
* @param[in] freq Clock output frequency
*/
void at86rf215_set_clock_output(at86rf215_t *dev,
at86rf215_clko_cur_t cur, at86rf215_clko_freq_t freq);
/**
* @brief Convenience function for simply sending data
*
* @note This function ignores the PRELOADING option
*
* @param[in,out] dev device to use for sending
* @param[in] data data to send (must include IEEE802.15.4 header)
* @param[in] len length of @p data
*
* @return number of bytes that were actually send
* @return or negative error code
*/
ssize_t at86rf215_send(at86rf215_t *dev, const void *data, size_t len);
/**
* @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,out] dev device to prepare for sending
*
* @return 0 on success, error otherwise
*/
int at86rf215_tx_prepare(at86rf215_t *dev);
/**
* @brief Load chunks of data into the transmit buffer of the given device
*
* @param[in,out] 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 at86rf215_tx_load(at86rf215_t *dev, const 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
*
* @return 0 on success, error otherwise
*/
int at86rf215_tx_exec(at86rf215_t *dev);
/**
* @brief Abort sending of data previously loaded into transmit buffer
*
* @param[in] dev device to abort TX on
*/
void at86rf215_tx_abort(at86rf215_t *dev);
/**
* @brief Signal that the transfer of the frame (and optional ACK reception)
* has finished. Sets the radio in RX mode.
*
* @param[in] dev device to use
*/
void at86rf215_tx_done(at86rf215_t *dev);
/**
* @brief Perform one manual channel clear assessment (CCA)
*
* The CCA mode and threshold level depends on the current transceiver settings.
*
* @param[in] dev device to use
*
* @return true if channel is determined clear
* @return false if channel is determined busy
*/
bool at86rf215_cca(at86rf215_t *dev);
/**
* @brief Generate an interrupt if supply voltage drops below the configured
* threshold.
*
* @param[in] dev device to configure
* @param[in] voltage Threshold voltage in mV
*
* @return 0 on success, error otherwise
*/
int at86rf215_enable_batmon(at86rf215_t *dev, unsigned voltage);
/**
* @brief Disable the Battery Monitor interrupt.
*
* @param[in] dev device to configure
*/
void at86rf215_disable_batmon(at86rf215_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* AT86RF215_H */
/** @} */