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

Merge pull request #12537 from benpicco/at86rfmega

drivers/at86rf2xx: add support for ATmegaRF MCUs
This commit is contained in:
Marian Buschsieweke 2019-10-28 09:22:02 +01:00 committed by GitHub
commit 4cf2151248
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 436 additions and 38 deletions

View File

@ -3,4 +3,8 @@ ifneq (,$(filter atmega_pcint,$(USEMODULE)))
USEMODULE += atmega_pcint1
endif
ifneq (,$(filter gnrc_netdev_default netdev_default,$(USEMODULE)))
USEMODULE += at86rfa1
endif
include $(RIOTCPU)/atmega_common/Makefile.dep

View File

@ -3,4 +3,8 @@ ifneq (,$(filter atmega_pcint,$(USEMODULE)))
USEMODULE += atmega_pcint1
endif
ifneq (,$(filter gnrc_netdev_default netdev_default,$(USEMODULE)))
USEMODULE += at86rfr2
endif
include $(RIOTCPU)/atmega_common/Makefile.dep

View File

@ -41,16 +41,20 @@ ifneq (,$(filter at30tse75x,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
endif
ifneq (,$(filter at86rf2%,$(USEMODULE)))
ifneq (,$(filter at86rf%,$(USEMODULE)))
USEMODULE += at86rf2xx
USEMODULE += xtimer
USEMODULE += luid
USEMODULE += netif
USEMODULE += ieee802154
USEMODULE += netdev_ieee802154
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_gpio_irq
FEATURES_REQUIRED += periph_spi
# only needed for SPI based variants
ifeq (,$(filter at86rfa1 at86rfr2,$(USEMODULE)))
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_gpio_irq
FEATURES_REQUIRED += periph_spi
endif
endif
ifneq (,$(filter ata8520e,$(USEMODULE)))

View File

@ -42,13 +42,49 @@ void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params)
netdev_t *netdev = (netdev_t *)dev;
netdev->driver = &at86rf2xx_driver;
/* initialize device descriptor */
dev->params = *params;
/* State to return after receiving or transmitting */
dev->idle_state = AT86RF2XX_STATE_TRX_OFF;
/* radio state is P_ON when first powered-on */
dev->state = AT86RF2XX_STATE_P_ON;
dev->pending_tx = 0;
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
(void) params;
/* set all interrupts off */
at86rf2xx_reg_write(dev, AT86RF2XX_REG__IRQ_MASK, 0x00);
#else
/* initialize device descriptor */
dev->params = *params;
#endif
}
static void at86rf2xx_disable_clock_output(at86rf2xx_t *dev)
{
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
(void) dev;
#else
uint8_t tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_CTRL_0);
tmp &= ~(AT86RF2XX_TRX_CTRL_0_MASK__CLKM_CTRL);
tmp &= ~(AT86RF2XX_TRX_CTRL_0_MASK__CLKM_SHA_SEL);
tmp |= (AT86RF2XX_TRX_CTRL_0_CLKM_CTRL__OFF);
at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_CTRL_0, tmp);
#endif
}
static void at86rf2xx_enable_smart_idle(at86rf2xx_t *dev)
{
#if AT86RF2XX_SMART_IDLE_LISTENING
uint8_t tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_RPC);
tmp |= (AT86RF2XX_TRX_RPC_MASK__RX_RPC_EN |
AT86RF2XX_TRX_RPC_MASK__PDT_RPC_EN |
AT86RF2XX_TRX_RPC_MASK__PLL_RPC_EN |
AT86RF2XX_TRX_RPC_MASK__XAH_TX_RPC_EN |
AT86RF2XX_TRX_RPC_MASK__IPAN_RPC_EN);
at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_RPC, tmp);
at86rf2xx_set_rxsensitivity(dev, RSSI_BASE_VAL);
#else
(void) dev;
#endif
}
void at86rf2xx_reset(at86rf2xx_t *dev)
@ -92,29 +128,18 @@ void at86rf2xx_reset(at86rf2xx_t *dev)
at86rf2xx_set_page(dev, AT86RF2XX_DEFAULT_PAGE);
#endif
#if !defined(MODULE_AT86RFA1) && !defined(MODULE_AT86RFR2)
/* don't populate masked interrupt flags to IRQ_STATUS register */
uint8_t tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_CTRL_1);
tmp &= ~(AT86RF2XX_TRX_CTRL_1_MASK__IRQ_MASK_MODE);
at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_CTRL_1, tmp);
/* configure smart idle listening feature */
#if AT86RF2XX_SMART_IDLE_LISTENING
tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_RPC);
tmp |= (AT86RF2XX_TRX_RPC_MASK__RX_RPC_EN |
AT86RF2XX_TRX_RPC_MASK__PDT_RPC_EN |
AT86RF2XX_TRX_RPC_MASK__PLL_RPC_EN |
AT86RF2XX_TRX_RPC_MASK__XAH_TX_RPC_EN |
AT86RF2XX_TRX_RPC_MASK__IPAN_RPC_EN);
at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_RPC, tmp);
at86rf2xx_set_rxsensitivity(dev, RSSI_BASE_VAL);
#endif
/* configure smart idle listening feature */
at86rf2xx_enable_smart_idle(dev);
/* disable clock output to save power */
tmp = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_CTRL_0);
tmp &= ~(AT86RF2XX_TRX_CTRL_0_MASK__CLKM_CTRL);
tmp &= ~(AT86RF2XX_TRX_CTRL_0_MASK__CLKM_SHA_SEL);
tmp |= (AT86RF2XX_TRX_CTRL_0_CLKM_CTRL__OFF);
at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_CTRL_0, tmp);
at86rf2xx_disable_clock_output(dev);
/* enable interrupts */
at86rf2xx_reg_write(dev, AT86RF2XX_REG__IRQ_MASK,

View File

@ -522,7 +522,14 @@ uint8_t at86rf2xx_set_state(at86rf2xx_t *dev, uint8_t state)
/* Discard all IRQ flags, framebuffer is lost anyway */
at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS);
/* Go to SLEEP mode from TRX_OFF */
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
/* reset interrupts states in device */
dev->irq_status = 0;
/* Setting SLPTR bit brings radio transceiver to sleep in in TRX_OFF*/
*AT86RF2XX_REG__TRXPR |= (AT86RF2XX_TRXPR_SLPTR);
#else
gpio_set(dev->params.sleep_pin);
#endif
dev->state = state;
}
else {

View File

@ -21,12 +21,14 @@
* @}
*/
#include "periph/spi.h"
#include "periph/gpio.h"
#include "xtimer.h"
#include "at86rf2xx_internal.h"
#include "at86rf2xx_registers.h"
#if !defined(MODULE_AT86RFA1) && !defined(MODULE_AT86RFR2)
#include "periph/spi.h"
#include "periph/gpio.h"
#define SPIDEV (dev->params.spi)
#define CSPIN (dev->params.cs_pin)
@ -101,6 +103,8 @@ void at86rf2xx_fb_stop(const at86rf2xx_t *dev)
spi_release(SPIDEV);
}
#endif /* SPI based transceiver */
uint8_t at86rf2xx_get_status(const at86rf2xx_t *dev)
{
/* if sleeping immediately return state */
@ -116,7 +120,13 @@ void at86rf2xx_assert_awake(at86rf2xx_t *dev)
{
if (at86rf2xx_get_status(dev) == AT86RF2XX_STATE_SLEEP) {
/* wake up and wait for transition to TRX_OFF */
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
/* Setting SLPTR bit in TRXPR to 0 returns the radio transceiver
* to the TRX_OFF state */
*AT86RF2XX_REG__TRXPR &= ~(AT86RF2XX_TRXPR_SLPTR);
#else
gpio_clear(dev->params.sleep_pin);
#endif
xtimer_usleep(AT86RF2XX_WAKEUP_DELAY);
/* update state: on some platforms, the timer behind xtimer
@ -134,9 +144,14 @@ void at86rf2xx_assert_awake(at86rf2xx_t *dev)
void at86rf2xx_hardware_reset(at86rf2xx_t *dev)
{
/* trigger hardware reset */
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
/* set reset Bit */
*(AT86RF2XX_REG__TRXPR) |= AT86RF2XX_TRXPR_TRXRST;
#else
gpio_clear(dev->params.reset_pin);
xtimer_usleep(AT86RF2XX_RESET_PULSE_WIDTH);
gpio_set(dev->params.reset_pin);
#endif
xtimer_usleep(AT86RF2XX_RESET_DELAY);
/* update state: if the radio state was P_ON (initialization phase),
@ -205,7 +220,7 @@ void at86rf2xx_configure_phy(at86rf2xx_t *dev)
at86rf2xx_set_state(dev, prev_state);
}
#if defined(MODULE_AT86RF233) || defined(MODULE_AT86RF231)
#if AT86RF2XX_RANDOM_NUMBER_GENERATOR
void at86rf2xx_get_random(const at86rf2xx_t *dev, uint8_t *data, size_t len)
{
for (size_t byteCount = 0; byteCount < len; ++byteCount) {

View File

@ -19,6 +19,7 @@
* @author Kévin Roussel <Kevin.Roussel@inria.fr>
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Josua Arndt <jarndt@ias.rwth-aachen.de>
*
* @}
*/
@ -58,6 +59,10 @@ const netdev_driver_t at86rf2xx_driver = {
.set = _set,
};
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
/* SOC has radio interrupts, store reference to netdev */
static netdev_t *at86rfmega_dev;
#else
static void _irq_handler(void *arg)
{
netdev_t *dev = (netdev_t *) arg;
@ -66,11 +71,15 @@ static void _irq_handler(void *arg)
dev->event_callback(dev, NETDEV_EVENT_ISR);
}
}
#endif
static int _init(netdev_t *netdev)
{
at86rf2xx_t *dev = (at86rf2xx_t *)netdev;
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
at86rfmega_dev = netdev;
#else
/* initialize GPIOs */
spi_init_cs(dev->params.spi, dev->params.cs_pin);
gpio_init(dev->params.sleep_pin, GPIO_OUT);
@ -87,6 +96,7 @@ static int _init(netdev_t *netdev)
return -EIO;
}
spi_release(dev->params.spi);
#endif
/* test if the device is responding */
if (at86rf2xx_reg_read(dev, AT86RF2XX_REG__PART_NUM) != AT86RF2XX_PARTNUM) {
@ -136,16 +146,20 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)
size_t pkt_len;
/* frame buffer protection will be unlocked as soon as at86rf2xx_fb_stop() is called,
* Set receiver to PLL_ON state to be able to free the SPI bus and avoid loosing data. */
* Set receiver to PLL_ON state to be able to free the SPI bus and avoid losing data. */
at86rf2xx_set_state(dev, AT86RF2XX_STATE_PLL_ON);
/* start frame buffer access */
at86rf2xx_fb_start(dev);
/* get the size of the received packet */
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
phr = TST_RX_LENGTH;
#else
at86rf2xx_fb_read(dev, &phr, 1);
#endif
/* ignore MSB (refer p.80) and substract length of FCS field */
/* ignore MSB (refer p.80) and subtract length of FCS field */
pkt_len = (phr & 0x7f) - 2;
/* return length when buf == NULL */
@ -184,7 +198,8 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)
* AT86RF232 RSSI_BASE_VAL + ED, base -91dBm
* AT86RF233 RSSI_BASE_VAL + ED, base -94dBm
* AT86RF231 RSSI_BASE_VAL + ED, base -91dBm
* AT***RFR2 RSSI_BASE_VAL + ED, base -90dBm
* AT86RFA1 RSSI_BASE_VAL + ED, base -90dBm
* AT86RFR2 RSSI_BASE_VAL + ED, base -90dBm
*
* AT86RF231 MAN. p.92, 8.4.3 Data Interpretation
* AT86RF232 MAN. p.91, 8.4.3 Data Interpretation
@ -200,7 +215,7 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)
netdev_ieee802154_rx_info_t *radio_info = info;
at86rf2xx_fb_read(dev, &(radio_info->lqi), 1);
#if defined(MODULE_AT86RF231)
#if defined(MODULE_AT86RF231) || defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
/* AT86RF231 does not provide ED at the end of the frame buffer, read
* from separate register instead */
at86rf2xx_fb_stop(dev);
@ -628,7 +643,12 @@ static void _isr(netdev_t *netdev)
}
/* read (consume) device status */
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
irq_mask = dev->irq_status;
dev->irq_status = 0;
#else
irq_mask = at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS);
#endif
trac_status = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_STATE)
& AT86RF2XX_TRX_STATE_MASK__TRAC;
@ -699,3 +719,74 @@ static void _isr(netdev_t *netdev)
}
}
}
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
/**
* @brief ISR for transceiver's receive end interrupt
*
* Is triggered when valid data is received. FCS check passed.
* Save IRQ status and inform upper layer of data reception.
*
* Flow Diagram Manual p. 52 / 63
*/
ISR(TRX24_RX_END_vect, ISR_BLOCK)
{
__enter_isr();
uint8_t status = *AT86RF2XX_REG__TRX_STATE & AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS;
DEBUG("TRX24_RX_END 0x%x\n", status);
((at86rf2xx_t *)at86rfmega_dev)->irq_status |= AT86RF2XX_IRQ_STATUS_MASK__RX_END;
/* Call upper layer to process received data */
at86rfmega_dev->event_callback(at86rfmega_dev, NETDEV_EVENT_ISR);
__exit_isr();
}
/**
* @brief Transceiver Frame Address Match, indicates incoming frame
*
* Is triggered when Frame with valid Address is received.
* Can be used to wake up MCU from sleep, etc.
*
* Flow Diagram Manual p. 52 / 63
*/
ISR(TRX24_XAH_AMI_vect, ISR_BLOCK)
{
__enter_isr();
DEBUG("TRX24_XAH_AMI\n");
((at86rf2xx_t *)at86rfmega_dev)->irq_status |= AT86RF2XX_IRQ_STATUS_MASK__AMI;
__exit_isr();
}
/**
* @brief ISR for transceiver's transmit end interrupt
*
* Is triggered when data or when acknowledge frames where send.
*
* Flow Diagram Manual p. 52 / 63
*/
ISR(TRX24_TX_END_vect, ISR_BLOCK)
{
__enter_isr();
at86rf2xx_t *dev = (at86rf2xx_t *) at86rfmega_dev;
uint8_t status = *AT86RF2XX_REG__TRX_STATE & AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS;
DEBUG("TRX24_TX_END 0x%x\n", status);
/* only inform upper layer when a transmission was done,
* not for sending acknowledge frames if data was received. */
if (status != AT86RF2XX_STATE_RX_AACK_ON) {
dev->irq_status |= AT86RF2XX_IRQ_STATUS_MASK__TX_END;
/* Call upper layer to process if data was send successful */
at86rfmega_dev->event_callback(at86rfmega_dev, NETDEV_EVENT_ISR);
}
__exit_isr();
}
#endif /* MODULE_AT86RFA1 || MODULE_AT86RFR2 */

View File

@ -28,6 +28,11 @@
#include "at86rf2xx.h"
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
#include <string.h>
#include "at86rf2xx_registers.h"
#endif
#ifdef __cplusplus
extern "C" {
@ -81,7 +86,14 @@ extern "C" {
*
* @return the value of the specified register
*/
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
static inline uint8_t at86rf2xx_reg_read(const at86rf2xx_t *dev, volatile uint8_t *addr) {
(void) dev;
return *addr;
}
#else
uint8_t at86rf2xx_reg_read(const at86rf2xx_t *dev, uint8_t addr);
#endif
/**
* @brief Write to a register at address `addr` from device `dev`.
@ -90,7 +102,15 @@ uint8_t at86rf2xx_reg_read(const at86rf2xx_t *dev, uint8_t addr);
* @param[in] addr address of the register to write
* @param[in] value value to write to the given register
*/
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
static inline void at86rf2xx_reg_write(const at86rf2xx_t *dev, volatile uint8_t *addr,
const uint8_t value) {
(void) dev;
*addr = value;
}
#else
void at86rf2xx_reg_write(const at86rf2xx_t *dev, uint8_t addr, uint8_t value);
#endif
/**
* @brief Read a chunk of data from the SRAM of the given device
@ -100,9 +120,16 @@ void at86rf2xx_reg_write(const at86rf2xx_t *dev, uint8_t addr, uint8_t value);
* @param[out] data buffer to read data into
* @param[in] len number of bytes to read from SRAM
*/
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
static inline void at86rf2xx_sram_read(const at86rf2xx_t *dev, uint8_t offset,
uint8_t *data, size_t len) {
(void)dev;
memcpy(data, (void*)(AT86RF2XX_REG__TRXFBST + offset), len);
}
#else
void at86rf2xx_sram_read(const at86rf2xx_t *dev, uint8_t offset,
uint8_t *data, size_t len);
#endif
/**
* @brief Write a chunk of data into the SRAM of the given device
*
@ -111,9 +138,16 @@ void at86rf2xx_sram_read(const at86rf2xx_t *dev, uint8_t offset,
* @param[in] data data to copy into SRAM
* @param[in] len number of bytes to write to SRAM
*/
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
static inline void at86rf2xx_sram_write(const at86rf2xx_t *dev, uint8_t offset,
const uint8_t *data, size_t len) {
(void)dev;
memcpy((void*)(AT86RF2XX_REG__TRXFBST + offset), data, len);
}
#else
void at86rf2xx_sram_write(const at86rf2xx_t *dev, uint8_t offset,
const uint8_t *data, size_t len);
#endif
/**
* @brief Start a read transcation internal frame buffer of the given device
*
@ -122,8 +156,13 @@ void at86rf2xx_sram_write(const at86rf2xx_t *dev, uint8_t offset,
*
* @param[in] dev device to start read
*/
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
static inline void at86rf2xx_fb_start(const at86rf2xx_t *dev) {
(void) dev;
}
#else
void at86rf2xx_fb_start(const at86rf2xx_t *dev);
#endif
/**
* @brief Read the internal frame buffer of the given device
*
@ -133,8 +172,14 @@ void at86rf2xx_fb_start(const at86rf2xx_t *dev);
* @param[out] data buffer to copy the data to
* @param[in] len number of bytes to read from the frame buffer
*/
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
static inline void at86rf2xx_fb_read(const at86rf2xx_t *dev, uint8_t *data, size_t len) {
(void)dev;
memcpy(data, (void*)AT86RF2XX_REG__TRXFBST, len);
}
#else
void at86rf2xx_fb_read(const at86rf2xx_t *dev, uint8_t *data, size_t len);
#endif
/**
* @brief Stop a read transcation internal frame buffer of the given device
*
@ -142,8 +187,13 @@ void at86rf2xx_fb_read(const at86rf2xx_t *dev, uint8_t *data, size_t len);
*
* @param[in] dev device to stop read
*/
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
static inline void at86rf2xx_fb_stop(const at86rf2xx_t *dev) {
(void) dev;
}
#else
void at86rf2xx_fb_stop(const at86rf2xx_t *dev);
#endif
/**
* @brief Convenience function for reading the status of the given device
*
@ -175,7 +225,7 @@ void at86rf2xx_hardware_reset(at86rf2xx_t *dev);
*/
void at86rf2xx_configure_phy(at86rf2xx_t *dev);
#if defined(MODULE_AT86RF233) || defined(MODULE_AT86RF231) || defined(DOXYGEN)
#if AT86RF2XX_RANDOM_NUMBER_GENERATOR || defined(DOXYGEN)
/**
* @brief Read random data from the RNG
*

View File

@ -62,10 +62,17 @@ extern "C" {
/**
* @brief AT86RF231 configuration
*/
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
static const uint8_t at86rf2xx_params[] =
{
0 /* dummy value */
};
#else
static const at86rf2xx_params_t at86rf2xx_params[] =
{
AT86RF2XX_PARAMS
};
#endif
#ifdef __cplusplus
}

View File

@ -38,6 +38,8 @@ extern "C" {
#define AT86RF231_PARTNUM (0x03)
#define AT86RF232_PARTNUM (0x0a)
#define AT86RF233_PARTNUM (0x0b)
#define AT86RFA1_PARTNUM (0x83)
#define AT86RFR2_PARTNUM (0x94)
/** @} */
/**
@ -50,11 +52,137 @@ extern "C" {
#define AT86RF2XX_PARTNUM AT86RF232_PARTNUM
#elif MODULE_AT86RF233
#define AT86RF2XX_PARTNUM AT86RF233_PARTNUM
#elif MODULE_AT86RFA1
#define AT86RF2XX_PARTNUM AT86RFA1_PARTNUM
#elif MODULE_AT86RFR2
#define AT86RF2XX_PARTNUM AT86RFR2_PARTNUM
#else /* MODULE_AT86RF231 as default device */
#define AT86RF2XX_PARTNUM AT86RF231_PARTNUM
#endif
/** @} */
/*
* memory-mapped transceiver
*/
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
#include <avr/io.h>
/**
* @name Register addresses
* @{
*/
#define AT86RF2XX_REG__TRX_STATUS (&TRX_STATUS)
#define AT86RF2XX_REG__TRX_STATE (&TRX_STATE)
#define AT86RF2XX_REG__TRX_CTRL_0 (&TRX_CTRL_0)
#define AT86RF2XX_REG__TRX_CTRL_1 (&TRX_CTRL_1)
#define AT86RF2XX_REG__PHY_TX_PWR (&PHY_TX_PWR)
#define AT86RF2XX_REG__PHY_RSSI (&PHY_RSSI)
#define AT86RF2XX_REG__PHY_ED_LEVEL (&PHY_ED_LEVEL)
#define AT86RF2XX_REG__PHY_CC_CCA (&PHY_CC_CCA)
#define AT86RF2XX_REG__CCA_THRES (&CCA_THRES)
#define AT86RF2XX_REG__RX_CTRL (&RX_CTRL)
#define AT86RF2XX_REG__SFD_VALUE (&SFD_VALUE)
#define AT86RF2XX_REG__TRX_CTRL_2 (&TRX_CTRL_2)
#define AT86RF2XX_REG__ANT_DIV (&ANT_DIV)
#define AT86RF2XX_REG__IRQ_MASK (&IRQ_MASK)
#define AT86RF2XX_REG__IRQ_STATUS (&IRQ_STATUS)
#define AT86RF2XX_REG__IRQ_STATUS1 (&IRQ_STATUS1)
#define AT86RF2XX_REG__VREG_CTRL (&VREG_CTRL)
#define AT86RF2XX_REG__BATMON (&BATMON)
#define AT86RF2XX_REG__XOSC_CTRL (&XOSC_CTRL)
#define AT86RF2XX_REG__CC_CTRL_0 (&CC_CTRL_0)
#define AT86RF2XX_REG__CC_CTRL_1 (&CC_CTRL_1)
#define AT86RF2XX_REG__RX_SYN (&RX_SYN)
#define AT86RF2XX_REG__XAH_CTRL_1 (&XAH_CTRL_1)
#define AT86RF2XX_REG__FTN_CTRL (&FTN_CTRL)
#define AT86RF2XX_REG__PLL_CF (&PLL_CF)
#define AT86RF2XX_REG__PLL_DCU (&PLL_DCU)
#define AT86RF2XX_REG__PART_NUM (&PART_NUM)
#define AT86RF2XX_REG__VERSION_NUM (&VERSION_NUM)
#define AT86RF2XX_REG__MAN_ID_0 (&MAN_ID_0)
#define AT86RF2XX_REG__MAN_ID_1 (&MAN_ID_1)
#define AT86RF2XX_REG__SHORT_ADDR_0 (&SHORT_ADDR_0)
#define AT86RF2XX_REG__SHORT_ADDR_1 (&SHORT_ADDR_1)
#define AT86RF2XX_REG__PAN_ID_0 (&PAN_ID_0)
#define AT86RF2XX_REG__PAN_ID_1 (&PAN_ID_1)
#define AT86RF2XX_REG__IEEE_ADDR_0 (&IEEE_ADDR_0)
#define AT86RF2XX_REG__IEEE_ADDR_1 (&IEEE_ADDR_1)
#define AT86RF2XX_REG__IEEE_ADDR_2 (&IEEE_ADDR_2)
#define AT86RF2XX_REG__IEEE_ADDR_3 (&IEEE_ADDR_3)
#define AT86RF2XX_REG__IEEE_ADDR_4 (&IEEE_ADDR_4)
#define AT86RF2XX_REG__IEEE_ADDR_5 (&IEEE_ADDR_5)
#define AT86RF2XX_REG__IEEE_ADDR_6 (&IEEE_ADDR_6)
#define AT86RF2XX_REG__IEEE_ADDR_7 (&IEEE_ADDR_7)
#define AT86RF2XX_REG__XAH_CTRL_0 (&XAH_CTRL_0)
#define AT86RF2XX_REG__CSMA_SEED_0 (&CSMA_SEED_0)
#define AT86RF2XX_REG__CSMA_SEED_1 (&CSMA_SEED_1)
#define AT86RF2XX_REG__CSMA_BE (&CSMA_BE)
#define AT86RF2XX_REG__TST_CTRL_DIGI (&TST_CTRL_DIGI)
#define AT86RF2XX_REG__TRXFBST (&TRXFBST)
#define AT86RF2XX_REG__TRXFBEND (&TRXFBEND)
#define AT86RF2XX_REG__TRXPR (&TRXPR)
/** @} */
/**
* @name Bitfield definitions for the TRX_CTRL_0 register
* @{
*/
#define AT86RF2XX_TRX_CTRL_0_MASK__PMU_EN (0x40)
#define AT86RF2XX_TRX_CTRL_0_MASK__PMU_START (0x20)
#define AT86RF2XX_TRX_CTRL_0_MASK__PMU_IF_INV (0x10)
/** @} */
/**
* @name Bitfield definitions for the TRX_CTRL_1 register
* @{
*/
#define AT86RF2XX_TRX_CTRL_1_MASK__PA_EXT_EN (0x80)
#define AT86RF2XX_TRX_CTRL_1_MASK__IRQ_2_EXT_EN (0x40)
#define AT86RF2XX_TRX_CTRL_1_MASK__TX_AUTO_CRC_ON (0x20)
#define AT86RF2XX_TRX_CTRL_1_MASK__PLL_TX_FLT (0x10)
/** @} */
/**
* @name Bitfield definitions for the TRX_CTRL_2 register
* @{
*/
#define AT86RF2XX_TRX_CTRL_2_MASK__RX_SAFE_MODE (0x80)
#define AT86RF2XX_TRX_CTRL_2_MASK__OQPSK_DATA_RATE (0x03)
/** @} */
/**
* @name Bitfield definitions for the IRQ_MASK/IRQ_STATUS register
* @{
*/
#define AT86RF2XX_IRQ_STATUS_MASK__AWAKE (0x80)
#define AT86RF2XX_IRQ_STATUS_MASK__TX_END (0x40)
#define AT86RF2XX_IRQ_STATUS_MASK__AMI (0x20)
#define AT86RF2XX_IRQ_STATUS_MASK__CCA_ED_DONE (0x10)
#define AT86RF2XX_IRQ_STATUS_MASK__RX_END (0x08)
#define AT86RF2XX_IRQ_STATUS_MASK__RX_START (0x04)
#define AT86RF2XX_IRQ_STATUS_MASK__PLL_UNLOCK (0x02)
#define AT86RF2XX_IRQ_STATUS_MASK__PLL_LOCK (0x01)
/* Map TX_END and RX_END to TRX_END to be compatible to SPI Devices */
#define AT86RF2XX_IRQ_STATUS_MASK__TRX_END (0x48)
/**
* @name Bitfield definitions for the IRQ_MASK1/IRQ_STATUS1 register
* @{
*/
#define AT86RF2XX_IRQ_STATUS_MASK1__TX_START (0x01)
#define AT86RF2XX_IRQ_STATUS_MASK1__MAF_0_AMI (0x02)
#define AT86RF2XX_IRQ_STATUS_MASK1__MAF_1_AMI (0x04)
#define AT86RF2XX_IRQ_STATUS_MASK1__MAF_2_AMI (0x08)
#define AT86RF2XX_IRQ_STATUS_MASK1__MAF_3_AMI (0x10)
/** @} */
#else
/*
* SPI based transceiver
*/
/**
* @name SPI access specifiers
* @{
@ -190,6 +318,7 @@ extern "C" {
#define AT86RF2XX_IRQ_STATUS_MASK__PLL_LOCK (0x01)
/** @} */
#endif /* END external spi transceiver */
/**
* @name Bitfield definitions for the TRX_STATUS register
* @{
@ -363,6 +492,18 @@ extern "C" {
#define AT86RF2XX_CSMA_SEED_1__CSMA_SEED_1 (0x07)
/** @} */
/**
* @name Bitfield definitions for the TRXPR Transceiver Pin Register
* @{
*/
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
#define AT86RF2XX_TRXPR_ATBE (0x08)
#define AT86RF2XX_TRXPR_TRXTST (0x04)
#define AT86RF2XX_TRXPR_SLPTR (0x02)
#define AT86RF2XX_TRXPR_TRXRST (0x01)
#endif
/** @} */
/**
* @name Bitfield definitions for the RF_CTRL_0 register
* @{

View File

@ -33,12 +33,16 @@
#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"
/* we need no peripherals for memory mapped radios */
#if !defined(MODULE_AT86RFA1) && !defined(MODULE_AT86RFR2)
#include "periph/spi.h"
#include "periph/gpio.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -83,6 +87,8 @@ extern "C" {
* for other seetings this value may change.
*/
# define RSSI_BASE_VAL (-98)
#elif MODULE_AT86RFA1 || MODULE_AT86RFR2
# define RSSI_BASE_VAL (-90)
#else
# define RSSI_BASE_VAL (-91)
#endif
@ -94,6 +100,8 @@ extern "C" {
# define MAX_RX_SENSITIVITY (-52)
#elif MODULE_AT86RF212B
# define MAX_RX_SENSITIVITY (-54)
#elif MODULE_AT86RFA1 || MODULE_AT86RFR2
# define MAX_RX_SENSITIVITY (-48)
#else
# define MAX_RX_SENSITIVITY (-49)
#endif
@ -105,6 +113,8 @@ extern "C" {
# define MIN_RX_SENSITIVITY (-101)
#elif MODULE_AT86RF212B
# define MIN_RX_SENSITIVITY (-110)
#elif MODULE_AT86RFA1 || MODULE_AT86RFR2
# define MIN_RX_SENSITIVITY (-100)
#else
# define MIN_RX_SENSITIVITY (-101)
#endif
@ -123,6 +133,23 @@ extern "C" {
#define AT86RF2XX_HAVE_RETRIES (0)
#endif
/**
* @brief Random Number Generator
*
* Most AT86RF radios have the option to use the highest bits of the RSSI
* register as a source of randomness.
* See Section 11.2 of the at86rf233 reference manual. (RND_VALUE)
*/
#if defined(MODULE_AT86RF233) || defined(MODULE_AT86RF231) || defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
#ifndef AT86RF2XX_RANDOM_NUMBER_GENERATOR
#define AT86RF2XX_RANDOM_NUMBER_GENERATOR (1)
#endif
#else
#ifndef AT86RF2XX_RANDOM_NUMBER_GENERATOR
#define AT86RF2XX_RANDOM_NUMBER_GENERATOR (0)
#endif
#endif
/**
* @brief Smart idle listening feature
*
@ -180,6 +207,12 @@ extern "C" {
/** @} */
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
/**
* @brief memory mapped radio needs no parameters
*/
typedef void at86rf2xx_params_t;
#else
/**
* @brief struct holding all params needed for device initialization
*/
@ -191,6 +224,7 @@ typedef struct at86rf2xx_params {
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;
#endif
/**
* @brief Device descriptor for AT86RF2XX radio devices
@ -199,8 +233,19 @@ typedef struct at86rf2xx_params {
*/
typedef struct {
netdev_ieee802154_t netdev; /**< netdev parent struct */
#if defined(MODULE_AT86RFA1) || defined(MODULE_AT86RFR2)
/* ATmega256rfr2 signals transceiver events with different interrupts
* they have to be stored to mimic the same flow as external transceiver
* Use irq_status to map saved interrupts of SOC transceiver,
* as they clear after IRQ callback.
*
* irq_status = IRQ_STATUS
*/
uint8_t irq_status; /**< save irq status */
#else
/* device specific fields */
at86rf2xx_params_t params; /**< parameters for initialization */
#endif
uint16_t flags; /**< Device specific flags */
uint8_t state; /**< current state of the radio */
uint8_t tx_frame_len; /**< length of the current TX frame */

View File

@ -36,7 +36,7 @@ USEMODULE += saul_default
BOARD_PROVIDES_NETIF := acd52832 airfy-beacon b-l072z-lrwan1 cc2538dk fox \
hamilton iotlab-m3 iotlab-a8-m3 lobaro-lorabox lsn50 mulle microbit msba2 \
native nrf51dk nrf51dongle nrf52dk nrf52840dk nrf52840-mdk nrf6310 \
microduino-corerf native nrf51dk nrf51dongle nrf52dk nrf52840dk nrf52840-mdk nrf6310 \
nucleo-f767zi openmote-b openmote-cc2538 pba-d-01-kw2x remote-pa remote-reva \
ruuvitag samr21-xpro samr30-xpro spark-core telosb thingy52 yunjia-nrf51822 z1

View File

@ -9,6 +9,7 @@ BOARD_INSUFFICIENT_MEMORY := \
i-nucleo-lrwan1 \
msb-430 \
msb-430h \
microduino-corerf \
nucleo-f030r8 \
nucleo-f031k6 \
nucleo-f042k6 \

View File

@ -94,6 +94,8 @@ PSEUDOMODULES += od_string
# include variants of the AT86RF2xx drivers as pseudo modules
PSEUDOMODULES += at86rf23%
PSEUDOMODULES += at86rf21%
PSEUDOMODULES += at86rfa1
PSEUDOMODULES += at86rfr2
# include variants of the BMX280 drivers as pseudo modules
PSEUDOMODULES += bmp280

View File

@ -9,6 +9,7 @@ BOARD_INSUFFICIENT_MEMORY := \
i-nucleo-lrwan1 \
msb-430 \
msb-430h \
microduino-corerf \
nucleo-f030r8 \
nucleo-f031k6 \
nucleo-f042k6 \

View File

@ -16,6 +16,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-f334r8 \
nucleo-l031k6 \
nucleo-l053r8 \
microduino-corerf \
stm32f030f4-demo \
stm32f0discovery \
stm32l0538-disco \