/* * Copyright (C) 2015 Freie Universität Berlin * * 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_at86rf2xx AT86RF2xx based drivers * @ingroup drivers_netdev * * This module contains drivers for radio devices in Atmel's AT86RF2xx series. * The driver is aimed to work with all devices of this series. * * @{ * * @file * @brief Interface definition for AT86RF2xx based drivers * * @author Thomas Eichinger * @author Hauke Petersen * @author Kaspar Schleiser * @author Daniel Krebs * @author Kévin Roussel * @author Joakim Nohlgård */ #ifndef AT86RF2XX_H_ #define AT86RF2XX_H_ #include #include "board.h" #include "periph/spi.h" #include "periph/gpio.h" #include "net/gnrc/netdev.h" #ifdef __cplusplus extern "C" { #endif /** * @brief Maximum possible packet size in byte */ #define AT86RF2XX_MAX_PKT_LENGTH (127) /** * @brief Default addresses used if the CPUID module is not present * @{ */ #define AT86RF2XX_DEFAULT_ADDR_SHORT (0x0230) #define AT86RF2XX_DEFAULT_ADDR_LONG (0x1222334455667788) /** @} */ /** * @brief Channel configuration * @{ */ #ifdef MODULE_AT86RF212B /* the AT86RF212B has a sub-1GHz radio */ #define AT86RF2XX_MIN_CHANNEL (0) #define AT86RF2XX_MAX_CHANNEL (10) #define AT86RF2XX_DEFAULT_CHANNEL (5) #else #define AT86RF2XX_MIN_CHANNEL (11U) #define AT86RF2XX_MAX_CHANNEL (26U) #define AT86RF2XX_DEFAULT_CHANNEL (26U) #endif /** @} */ /** * @brief Default PAN ID * * @todo Read some global network stack specific configuration value */ #define AT86RF2XX_DEFAULT_PANID (0x0023) /** * @brief Default TX power (0dBm) */ #define AT86RF2XX_DEFAULT_TXPOWER (0U) /** * @brief Base (minimal) RSSI value in dBm */ #define RSSI_BASE_VAL (-91) /** * @brief Flags for device internal states (see datasheet) * @{ */ #define AT86RF2XX_STATE_TRX_OFF (0x08) /**< idle */ #define AT86RF2XX_STATE_PLL_ON (0x09) /**< ready to transmit */ #define AT86RF2XX_STATE_SLEEP (0x0f) /**< sleep mode */ #define AT86RF2XX_STATE_BUSY_RX_AACK (0x11) /**< busy receiving data */ #define AT86RF2XX_STATE_BUSY_TX_ARET (0x12) /**< busy transmitting data */ #define AT86RF2XX_STATE_RX_AACK_ON (0x16) /**< wait for incoming data */ #define AT86RF2XX_STATE_TX_ARET_ON (0x19) /**< ready for sending data */ #define AT86RF2XX_STATE_IN_PROGRESS (0x1f) /**< ongoing state conversion */ /** @} */ /** * @brief Internal device option flags * @{ */ #define AT86RF2XX_OPT_AUTOACK (0x0001) /**< auto ACKs active */ #define AT86RF2XX_OPT_CSMA (0x0002) /**< CSMA active */ #define AT86RF2XX_OPT_PROMISCUOUS (0x0004) /**< promiscuous mode * active */ #define AT86RF2XX_OPT_PRELOADING (0x0008) /**< preloading enabled */ #define AT86RF2XX_OPT_TELL_TX_START (0x0010) /**< notify MAC layer on TX * start */ #define AT86RF2XX_OPT_TELL_TX_END (0x0020) /**< notify MAC layer on TX * finished */ #define AT86RF2XX_OPT_TELL_RX_START (0x0040) /**< notify MAC layer on RX * start */ #define AT86RF2XX_OPT_TELL_RX_END (0x0080) /**< notify MAC layer on RX * finished */ #define AT86RF2XX_OPT_RAWDUMP (0x0100) /**< pass RAW frame data to * upper layer */ #define AT86RF2XX_OPT_SRC_ADDR_LONG (0x0200) /**< send data using long * source address */ #define AT86RF2XX_OPT_USE_SRC_PAN (0x0400) /**< do not compress source * PAN ID */ /** @} */ /** * @brief Device descriptor for AT86RF2XX radio devices */ typedef struct { /* netdev fields */ const gnrc_netdev_driver_t *driver; /**< pointer to the devices interface */ gnrc_netdev_event_cb_t event_cb; /**< netdev event callback */ kernel_pid_t mac_pid; /**< the driver's thread's PID */ /* device specific fields */ spi_t spi; /**< used SPI device */ gpio_t cs_pin; /**< chip select pin */ gpio_t sleep_pin; /**< sleep pin */ gpio_t reset_pin; /**< reset pin */ gpio_t int_pin; /**< external interrupt pin */ gnrc_nettype_t proto; /**< protocol the radio expects */ uint8_t state; /**< current state of the radio */ uint8_t seq_nr; /**< sequence number to use next */ uint8_t frame_len; /**< length of the current TX frame */ uint16_t pan; /**< currently used PAN ID */ uint8_t chan; /**< currently used channel number */ #ifdef MODULE_AT86RF212B /* Only AT86RF212B supports multiple pages (PHY modes) */ uint8_t page; /**< currently used channel page */ #endif uint8_t addr_short[2]; /**< the radio's short address */ uint8_t addr_long[8]; /**< the radio's long address */ uint16_t options; /**< state of used options */ uint8_t idle_state; /**< state to return to after sending */ } at86rf2xx_t; /** * @brief struct holding all params needed for device initialization */ typedef struct at86rf2xx_params { spi_t spi; /**< SPI bus the device is connected to */ spi_speed_t spi_speed; /**< SPI speed to use */ gpio_t cs_pin; /**< GPIO pin connected to chip select */ gpio_t int_pin; /**< GPIO pin connected to the interrupt pin */ gpio_t sleep_pin; /**< GPIO pin connected to the sleep pin */ gpio_t reset_pin; /**< GPIO pin connected to the reset pin */ } at86rf2xx_params_t; /** * @brief Initialize a given AT86RF2xx device * * @param[out] dev device descriptor * @param[in] spi SPI bus the device is connected to * @param[in] spi_speed SPI speed to use * @param[in] cs_pin GPIO pin connected to chip select * @param[in] int_pin GPIO pin connected to the interrupt pin * @param[in] sleep_pin GPIO pin connected to the sleep pin * @param[in] reset_pin GPIO pin connected to the reset pin * * @return 0 on success * @return <0 on error */ int at86rf2xx_init(at86rf2xx_t *dev, spi_t spi, spi_speed_t spi_speed, gpio_t cs_pin, gpio_t int_pin, gpio_t sleep_pin, gpio_t reset_pin); /** * @brief Trigger a hardware reset and configure radio with default values * * @param[in] dev device to reset */ void at86rf2xx_reset(at86rf2xx_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 at86rf2xx_cca(at86rf2xx_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 at86rf2xx_get_addr_short(at86rf2xx_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 at86rf2xx_set_addr_short(at86rf2xx_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 at86rf2xx_get_addr_long(at86rf2xx_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 at86rf2xx_set_addr_long(at86rf2xx_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 at86rf2xx_get_chan(at86rf2xx_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 at86rf2xx_set_chan(at86rf2xx_t *dev, uint8_t chan); /** * @brief Get the configured channel page of the given device * * @param[in] dev device to read from * * @return the currently set channel page */ uint8_t at86rf2xx_get_page(at86rf2xx_t *dev); /** * @brief Set the channel page of the given device * * @param[in] dev device to write to * @param[in] page channel page to set */ void at86rf2xx_set_page(at86rf2xx_t *dev, uint8_t page); /** * @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 at86rf2xx_get_pan(at86rf2xx_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 at86rf2xx_set_pan(at86rf2xx_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 at86rf2xx_get_txpower(at86rf2xx_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 at86rf2xx_set_txpower(at86rf2xx_t *dev, int16_t txpower); /** * @brief Get the maximum number of retransmissions * * @param[in] dev device to read from * * @return configured number of retransmissions */ uint8_t at86rf2xx_get_max_retries(at86rf2xx_t *dev); /** * @brief Set the maximum number of retransmissions * * This setting specifies the number of attempts to retransmit a frame, when it * was not acknowledged by the recipient, before the transaction gets cancelled. * The maximum value is 7. * * @param[in] dev device to write to * @param[in] max the maximum number of retransmissions */ void at86rf2xx_set_max_retries(at86rf2xx_t *dev, uint8_t max); /** * @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 at86rf2xx_get_csma_max_retries(at86rf2xx_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 at86rf2xx_set_csma_max_retries(at86rf2xx_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 at86rf2xx_set_csma_backoff_exp(at86rf2xx_t *dev, uint8_t min, uint8_t max); /** * @brief Set seed for CSMA random backoff * * @param[in] dev device to write to * @param[in] entropy 11 bit of entropy as seed for random backoff */ void at86rf2xx_set_csma_seed(at86rf2xx_t *dev, uint8_t entropy[2]); /** * @brief Get the CCA threshold value * * @param[in] dev device to read value from * * @return the current CCA threshold value */ int8_t at86rf2xx_get_cca_threshold(at86rf2xx_t *dev); /** * @brief Set the CCA threshold value * * @param[in] dev device to write to * @param[in] value the new CCA threshold value */ void at86rf2xx_set_cca_threshold(at86rf2xx_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 at86rf2xx_set_option(at86rf2xx_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 at86rf2xx_set_state(at86rf2xx_t *dev, uint8_t state); /** * @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 at86rf2xx_reset_state_machine(at86rf2xx_t *dev); /** * @brief Convenience function for simply sending data * * @note This function ignores the PRELOADING option * * @param[in] 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 0 on error */ size_t at86rf2xx_send(at86rf2xx_t *dev, uint8_t *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] dev device to prepare for sending */ void at86rf2xx_tx_prepare(at86rf2xx_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 at86rf2xx_tx_load(at86rf2xx_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 at86rf2xx_tx_exec(at86rf2xx_t *dev); /** * @brief Read the length of a received packet * * @param dev device to read from * * @return overall length of a received packet in byte */ size_t at86rf2xx_rx_len(at86rf2xx_t *dev); /** * @brief Read a chunk of data from the receive buffer of the given device * * @param[in] dev device to read from * @param[out] data buffer to write data to * @param[in] len number of bytes to read from device * @param[in] offset offset in the receive buffer */ void at86rf2xx_rx_read(at86rf2xx_t *dev, uint8_t *data, size_t len, size_t offset); #ifdef __cplusplus } #endif #endif /* AT86RF2XX_H_ */ /** @} */