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:
commit
4cf2151248
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)))
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
* @{
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -9,6 +9,7 @@ BOARD_INSUFFICIENT_MEMORY := \
|
||||
i-nucleo-lrwan1 \
|
||||
msb-430 \
|
||||
msb-430h \
|
||||
microduino-corerf \
|
||||
nucleo-f030r8 \
|
||||
nucleo-f031k6 \
|
||||
nucleo-f042k6 \
|
||||
|
@ -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
|
||||
|
@ -9,6 +9,7 @@ BOARD_INSUFFICIENT_MEMORY := \
|
||||
i-nucleo-lrwan1 \
|
||||
msb-430 \
|
||||
msb-430h \
|
||||
microduino-corerf \
|
||||
nucleo-f030r8 \
|
||||
nucleo-f031k6 \
|
||||
nucleo-f042k6 \
|
||||
|
@ -16,6 +16,7 @@ BOARD_INSUFFICIENT_MEMORY := \
|
||||
nucleo-f334r8 \
|
||||
nucleo-l031k6 \
|
||||
nucleo-l053r8 \
|
||||
microduino-corerf \
|
||||
stm32f030f4-demo \
|
||||
stm32f0discovery \
|
||||
stm32l0538-disco \
|
||||
|
Loading…
Reference in New Issue
Block a user