mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #18988 from jia200x/pr/at86rf2xx/isolate_netdev
drivers/at86rf2xx: isolate netdev logic
This commit is contained in:
commit
2e50d5e448
1
dist/tools/doccheck/exclude_patterns
vendored
1
dist/tools/doccheck/exclude_patterns
vendored
@ -7964,6 +7964,7 @@ drivers/include/at86rf215\.h:[0-9]+: warning: Member at86rf215_clko_cur_t \(enum
|
||||
drivers/include/at86rf215\.h:[0-9]+: warning: Member at86rf215_clko_freq_t \(enumeration\) of group drivers_at86rf215 is not documented\.
|
||||
drivers/include/at86rf215\.h:[0-9]+: warning: Member at86rf215_state_t \(enumeration\) of group drivers_at86rf215 is not documented\.
|
||||
drivers/include/at86rf2xx\.h:[0-9]+: warning: Member AT86RF2XX_DEFAULT_CHANNEL \(macro definition\) of group drivers_at86rf2xx is not documented\.
|
||||
drivers/include/at86rf2xx\.h:[0-9]+: warning: Member AT86RF2XX_DEFAULT_PAGE \(macro definition\) of group drivers_at86rf2xx is not documented\.
|
||||
drivers/include/at86rf2xx\.h:[0-9]+: warning: Member AT86RF2XX_MAX_CHANNEL \(macro definition\) of group drivers_at86rf2xx is not documented\.
|
||||
drivers/include/at86rf2xx\.h:[0-9]+: warning: Member AT86RF2XX_MIN_CHANNEL \(macro definition\) of group drivers_at86rf2xx is not documented\.
|
||||
drivers/include/bh1900nux\.h:[0-9]+: warning: Member BH1900NUX_REG_ADDR \(macro definition\) of group drivers_bh1900nux is not documented\.
|
||||
|
@ -27,13 +27,9 @@
|
||||
#include "kernel_defines.h"
|
||||
#include "byteorder.h"
|
||||
#include "net/ieee802154.h"
|
||||
#if IS_USED(IEEE802154_SECURITY)
|
||||
#include "net/ieee802154_security.h"
|
||||
#endif
|
||||
#include "net/gnrc.h"
|
||||
#include "at86rf2xx_registers.h"
|
||||
#include "at86rf2xx_internal.h"
|
||||
#include "at86rf2xx_netdev.h"
|
||||
#if IS_USED(MODULE_AT86RF2XX_AES_SPI)
|
||||
#include "at86rf2xx_aes.h"
|
||||
#endif
|
||||
@ -41,103 +37,6 @@
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#if IS_USED(MODULE_AT86RF2XX_AES_SPI) && \
|
||||
IS_USED(MODULE_IEEE802154_SECURITY)
|
||||
/**
|
||||
* @brief Pass the 802.15.4 encryption key to the transceiver hardware
|
||||
*
|
||||
* @param[in] dev Abstract security device descriptor
|
||||
* @param[in] key Encryption key to be used
|
||||
* @param[in] key_size Size of the encryption key in bytes
|
||||
*/
|
||||
static void _at86rf2xx_set_key(ieee802154_sec_dev_t *dev,
|
||||
const uint8_t *key, uint8_t key_size)
|
||||
{
|
||||
(void)key_size;
|
||||
at86rf2xx_aes_key_write_encrypt((at86rf2xx_t *)dev->ctx, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compute CBC-MAC from IEEE 802.15.4 security context
|
||||
*
|
||||
* @param[in] dev Abstract security device descriptor
|
||||
* @param[out] cipher Buffer to store cipher blocks
|
||||
* @param[in] iv Initial vector
|
||||
* @param[in] plain Input data blocks
|
||||
* @param[in] nblocks Number of blocks
|
||||
*/
|
||||
static void _at86rf2xx_cbc(const ieee802154_sec_dev_t *dev,
|
||||
uint8_t *cipher,
|
||||
uint8_t *iv,
|
||||
const uint8_t *plain,
|
||||
uint8_t nblocks)
|
||||
{
|
||||
at86rf2xx_aes_cbc_encrypt((at86rf2xx_t *)dev->ctx,
|
||||
(aes_block_t *)cipher,
|
||||
NULL,
|
||||
iv,
|
||||
(aes_block_t *)plain,
|
||||
nblocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform ECB encryption
|
||||
*
|
||||
* @param[in] dev Abstract security device descriptor
|
||||
* @param[out] cipher Output cipher blocks
|
||||
* @param[in] plain Plain blocks
|
||||
* @param[in] nblocks Number of blocks
|
||||
*/
|
||||
static void _at86rf2xx_ecb(const ieee802154_sec_dev_t *dev,
|
||||
uint8_t *cipher,
|
||||
const uint8_t *plain,
|
||||
uint8_t nblocks)
|
||||
{
|
||||
at86rf2xx_aes_ecb_encrypt((at86rf2xx_t *)dev->ctx,
|
||||
(aes_block_t *)cipher,
|
||||
NULL,
|
||||
(aes_block_t *)plain,
|
||||
nblocks);
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief Struct that contains IEEE 802.15.4 security operations
|
||||
* which are implemented, using the transceiver´s hardware
|
||||
* crypto capabilities
|
||||
*/
|
||||
static const ieee802154_radio_cipher_ops_t _at86rf2xx_cipher_ops = {
|
||||
.set_key = _at86rf2xx_set_key,
|
||||
.ecb = _at86rf2xx_ecb,
|
||||
.cbc = _at86rf2xx_cbc
|
||||
};
|
||||
#endif /* IS_USED(MODULE_AT86RF2XX_AES_SPI) && \
|
||||
IS_USED(MODULE_IEEE802154_SECURITY) */
|
||||
|
||||
void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params, uint8_t index)
|
||||
{
|
||||
netdev_t *netdev = &dev->netdev.netdev;
|
||||
|
||||
netdev->driver = &at86rf2xx_driver;
|
||||
/* 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 AT86RF2XX_IS_PERIPH
|
||||
(void) params;
|
||||
/* set all interrupts off */
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__IRQ_MASK, 0x00);
|
||||
#else
|
||||
/* initialize device descriptor */
|
||||
dev->params = *params;
|
||||
#endif
|
||||
|
||||
netdev_register(netdev, NETDEV_AT86RF2XX, index);
|
||||
/* set device address */
|
||||
netdev_ieee802154_setup(&dev->netdev);
|
||||
}
|
||||
|
||||
static void at86rf2xx_disable_clock_output(at86rf2xx_t *dev)
|
||||
{
|
||||
#if AT86RF2XX_IS_PERIPH
|
||||
@ -177,38 +76,25 @@ void at86rf2xx_disable_smart_idle(at86rf2xx_t *dev)
|
||||
void at86rf2xx_reset(at86rf2xx_t *dev)
|
||||
{
|
||||
uint8_t tmp;
|
||||
netdev_ieee802154_reset(&dev->netdev);
|
||||
|
||||
/* Reset state machine to ensure a known state */
|
||||
if (dev->state == AT86RF2XX_STATE_P_ON) {
|
||||
at86rf2xx_set_state(dev, AT86RF2XX_STATE_FORCE_TRX_OFF);
|
||||
}
|
||||
|
||||
/* set short and long address */
|
||||
at86rf2xx_set_addr_long(dev, (eui64_t *)dev->netdev.long_addr);
|
||||
at86rf2xx_set_addr_short(dev, (network_uint16_t *)dev->netdev.short_addr);
|
||||
/* set default channel, page and TX power */
|
||||
at86rf2xx_configure_phy(dev, AT86RF2XX_DEFAULT_CHANNEL, AT86RF2XX_DEFAULT_PAGE, AT86RF2XX_DEFAULT_TXPOWER);
|
||||
|
||||
/* set default channel */
|
||||
at86rf2xx_set_chan(dev, AT86RF2XX_DEFAULT_CHANNEL);
|
||||
/* set default TX power */
|
||||
at86rf2xx_set_txpower(dev, AT86RF2XX_DEFAULT_TXPOWER);
|
||||
/* set default options */
|
||||
|
||||
if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) {
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_AUTOACK, true);
|
||||
at86rf2xx_set_option(dev, AT86RF2XX_OPT_CSMA, true);
|
||||
|
||||
static const netopt_enable_t enable = NETOPT_ENABLE;
|
||||
netdev_ieee802154_set(&dev->netdev, NETOPT_ACK_REQ,
|
||||
&enable, sizeof(enable));
|
||||
}
|
||||
|
||||
/* enable safe mode (protect RX FIFO until reading data starts) */
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_CTRL_2,
|
||||
AT86RF2XX_TRX_CTRL_2_MASK__RX_SAFE_MODE);
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
at86rf2xx_set_page(dev, AT86RF2XX_DEFAULT_PAGE);
|
||||
#endif
|
||||
|
||||
#if !AT86RF2XX_IS_PERIPH
|
||||
/* don't populate masked interrupt flags to IRQ_STATUS register */
|
||||
@ -236,12 +122,6 @@ void at86rf2xx_reset(at86rf2xx_t *dev)
|
||||
/* clear interrupt flags */
|
||||
at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS);
|
||||
|
||||
#if IS_USED(MODULE_IEEE802154_SECURITY) && \
|
||||
IS_USED(MODULE_AT86RF2XX_AES_SPI)
|
||||
dev->netdev.sec_ctx.dev.cipher_ops = &_at86rf2xx_cipher_ops;
|
||||
dev->netdev.sec_ctx.dev.ctx = dev;
|
||||
#endif
|
||||
|
||||
/* State to return after receiving or transmitting */
|
||||
dev->idle_state = AT86RF2XX_PHY_STATE_RX;
|
||||
/* go into RX state */
|
||||
@ -255,19 +135,6 @@ void at86rf2xx_reset(at86rf2xx_t *dev)
|
||||
DEBUG("at86rf2xx_reset(): reset complete.\n");
|
||||
}
|
||||
|
||||
size_t at86rf2xx_send(at86rf2xx_t *dev, const uint8_t *data, size_t len)
|
||||
{
|
||||
/* check data length */
|
||||
if (len > AT86RF2XX_MAX_PKT_LENGTH) {
|
||||
DEBUG("[at86rf2xx] Error: data to send exceeds max packet size\n");
|
||||
return 0;
|
||||
}
|
||||
at86rf2xx_tx_prepare(dev);
|
||||
at86rf2xx_tx_load(dev, data, len, 0);
|
||||
at86rf2xx_tx_exec(dev);
|
||||
return len;
|
||||
}
|
||||
|
||||
void at86rf2xx_tx_prepare(at86rf2xx_t *dev)
|
||||
{
|
||||
uint8_t state;
|
||||
@ -290,8 +157,6 @@ size_t at86rf2xx_tx_load(at86rf2xx_t *dev, const uint8_t *data,
|
||||
|
||||
void at86rf2xx_tx_exec(at86rf2xx_t *dev)
|
||||
{
|
||||
netdev_t *netdev = &dev->netdev.netdev;
|
||||
|
||||
#if AT86RF2XX_HAVE_RETRIES
|
||||
dev->tx_retries = -1;
|
||||
#endif
|
||||
@ -301,9 +166,6 @@ void at86rf2xx_tx_exec(at86rf2xx_t *dev)
|
||||
/* trigger sending of pre-loaded frame */
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_STATE,
|
||||
AT86RF2XX_TRX_STATE__TX_START);
|
||||
if (netdev->event_callback) {
|
||||
netdev->event_callback(netdev, NETDEV_EVENT_TX_STARTED);
|
||||
}
|
||||
}
|
||||
|
||||
bool at86rf2xx_cca(at86rf2xx_t *dev)
|
||||
|
@ -51,127 +51,36 @@ static const uint8_t dbm_to_tx_pow_915[] = { 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x17,
|
||||
0x04, 0x03, 0x02, 0x01, 0x00, 0x86,
|
||||
0x40, 0x84, 0x83, 0x82, 0x80, 0xc1,
|
||||
0xc0 };
|
||||
static int16_t _tx_pow_to_dbm_212b(uint8_t channel, uint8_t page, uint8_t reg)
|
||||
{
|
||||
if (page == 0 || page == 2) {
|
||||
const uint8_t *dbm_to_tx_pow;
|
||||
size_t nelem;
|
||||
|
||||
if (channel == 0) {
|
||||
/* Channel 0 is 868.3 MHz */
|
||||
dbm_to_tx_pow = &dbm_to_tx_pow_868[0];
|
||||
nelem = ARRAY_SIZE(dbm_to_tx_pow_868);
|
||||
}
|
||||
else {
|
||||
/* Channels 1+ are 915 MHz */
|
||||
dbm_to_tx_pow = &dbm_to_tx_pow_915[0];
|
||||
nelem = ARRAY_SIZE(dbm_to_tx_pow_915);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nelem; ++i) {
|
||||
if (dbm_to_tx_pow[i] == reg) {
|
||||
return (i - AT86RF2XX_TXPOWER_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif MODULE_AT86RF233
|
||||
static const int16_t tx_pow_to_dbm[] = { 4, 4, 3, 3, 2, 2, 1,
|
||||
0, -1, -2, -3, -4, -6, -8, -12, -17 };
|
||||
static const uint8_t dbm_to_tx_pow[] = { 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e,
|
||||
0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c,
|
||||
0x0b, 0x0b, 0x0a, 0x09, 0x08, 0x07,
|
||||
0x06, 0x05, 0x03, 0x00 };
|
||||
#else
|
||||
static const int16_t tx_pow_to_dbm[] = { 3, 3, 2, 2, 1, 1, 0,
|
||||
-1, -2, -3, -4, -5, -7, -9, -12, -17 };
|
||||
static const uint8_t dbm_to_tx_pow[] = { 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e,
|
||||
0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
|
||||
0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
|
||||
0x05, 0x03, 0x00 };
|
||||
#endif
|
||||
|
||||
void at86rf2xx_get_addr_short(const at86rf2xx_t *dev, network_uint16_t *addr)
|
||||
{
|
||||
memcpy(addr, dev->netdev.short_addr, sizeof(*addr));
|
||||
}
|
||||
|
||||
void at86rf2xx_set_addr_short(at86rf2xx_t *dev, const network_uint16_t *addr)
|
||||
{
|
||||
memcpy(dev->netdev.short_addr, addr, sizeof(*addr));
|
||||
#ifdef MODULE_SIXLOWPAN
|
||||
/* https://tools.ietf.org/html/rfc4944#section-12 requires the first bit to
|
||||
* 0 for unicast addresses */
|
||||
dev->netdev.short_addr[0] &= 0x7F;
|
||||
#endif
|
||||
/* device use lsb first, not network byte order */
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__SHORT_ADDR_0,
|
||||
dev->netdev.short_addr[1]);
|
||||
addr->u8[1]);
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__SHORT_ADDR_1,
|
||||
dev->netdev.short_addr[0]);
|
||||
}
|
||||
|
||||
void at86rf2xx_get_addr_long(const at86rf2xx_t *dev, eui64_t *addr)
|
||||
{
|
||||
memcpy(addr, dev->netdev.long_addr, sizeof(*addr));
|
||||
addr->u8[0]);
|
||||
}
|
||||
|
||||
void at86rf2xx_set_addr_long(at86rf2xx_t *dev, const eui64_t *addr)
|
||||
{
|
||||
memcpy(dev->netdev.long_addr, addr, sizeof(*addr));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
/* device use lsb first, not network byte order */
|
||||
at86rf2xx_reg_write(dev, (AT86RF2XX_REG__IEEE_ADDR_0 + i),
|
||||
dev->netdev.long_addr[IEEE802154_LONG_ADDRESS_LEN - 1 - i]);
|
||||
addr->uint8[IEEE802154_LONG_ADDRESS_LEN - 1 - i]);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t at86rf2xx_get_chan(const at86rf2xx_t *dev)
|
||||
{
|
||||
return dev->netdev.chan;
|
||||
}
|
||||
|
||||
void at86rf2xx_set_chan(at86rf2xx_t *dev, uint8_t channel)
|
||||
{
|
||||
if ((channel > AT86RF2XX_MAX_CHANNEL)
|
||||
#if AT86RF2XX_MIN_CHANNEL /* is zero for sub-GHz */
|
||||
|| (channel < AT86RF2XX_MIN_CHANNEL)
|
||||
#endif
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
dev->netdev.chan = channel;
|
||||
|
||||
at86rf2xx_configure_phy(dev);
|
||||
}
|
||||
|
||||
uint8_t at86rf2xx_get_page(const at86rf2xx_t *dev)
|
||||
{
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
return dev->page;
|
||||
#else
|
||||
(void) dev;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void at86rf2xx_set_page(at86rf2xx_t *dev, uint8_t page)
|
||||
{
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
if ((page == 0) || (page == 2)) {
|
||||
dev->page = page;
|
||||
at86rf2xx_configure_phy(dev);
|
||||
}
|
||||
#else
|
||||
(void) dev;
|
||||
(void) page;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t at86rf2xx_get_phy_mode(at86rf2xx_t *dev)
|
||||
{
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
@ -214,11 +123,6 @@ uint8_t at86rf2xx_get_rate(at86rf2xx_t *dev)
|
||||
return rate;
|
||||
}
|
||||
|
||||
uint16_t at86rf2xx_get_pan(const at86rf2xx_t *dev)
|
||||
{
|
||||
return dev->netdev.pan;
|
||||
}
|
||||
|
||||
void at86rf2xx_set_pan(at86rf2xx_t *dev, uint16_t pan)
|
||||
{
|
||||
le_uint16_t le_pan = byteorder_htols(pan);
|
||||
@ -228,21 +132,9 @@ void at86rf2xx_set_pan(at86rf2xx_t *dev, uint16_t pan)
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__PAN_ID_1, le_pan.u8[1]);
|
||||
}
|
||||
|
||||
int16_t at86rf2xx_get_txpower(const at86rf2xx_t *dev)
|
||||
{
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
uint8_t txpower = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_TX_PWR);
|
||||
DEBUG("txpower value: %x\n", txpower);
|
||||
return _tx_pow_to_dbm_212b(dev->netdev.chan, dev->page, txpower);
|
||||
#else
|
||||
uint8_t txpower = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_TX_PWR)
|
||||
& AT86RF2XX_PHY_TX_PWR_MASK__TX_PWR;
|
||||
return tx_pow_to_dbm[txpower];
|
||||
#endif
|
||||
}
|
||||
|
||||
void at86rf2xx_set_txpower(const at86rf2xx_t *dev, int16_t txpower)
|
||||
static inline void _set_txpower(const at86rf2xx_t *dev, int16_t txpower, uint8_t channel)
|
||||
{
|
||||
(void) channel;
|
||||
txpower += AT86RF2XX_TXPOWER_OFF;
|
||||
|
||||
if (txpower < 0) {
|
||||
@ -252,11 +144,11 @@ void at86rf2xx_set_txpower(const at86rf2xx_t *dev, int16_t txpower)
|
||||
txpower = AT86RF2XX_TXPOWER_MAX;
|
||||
}
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
if (dev->netdev.chan == 0) {
|
||||
if (channel == 0) {
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__PHY_TX_PWR,
|
||||
dbm_to_tx_pow_868[txpower]);
|
||||
}
|
||||
else if (dev->netdev.chan < 11) {
|
||||
else if (channel < 11) {
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__PHY_TX_PWR,
|
||||
dbm_to_tx_pow_915[txpower]);
|
||||
}
|
||||
@ -266,6 +158,63 @@ void at86rf2xx_set_txpower(const at86rf2xx_t *dev, int16_t txpower)
|
||||
#endif
|
||||
}
|
||||
|
||||
void at86rf2xx_configure_phy(at86rf2xx_t *dev, uint8_t chan, uint8_t page, int16_t txpower)
|
||||
{
|
||||
/* we must be in TRX_OFF before changing the PHY configuration */
|
||||
uint8_t prev_state = at86rf2xx_set_state(dev, AT86RF2XX_STATE_TRX_OFF);
|
||||
(void) page;
|
||||
(void) chan;
|
||||
(void) txpower;
|
||||
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
/* The TX power register must be updated after changing the channel if
|
||||
* moving between bands. */
|
||||
|
||||
uint8_t trx_ctrl2 = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_CTRL_2);
|
||||
uint8_t rf_ctrl0 = at86rf2xx_reg_read(dev, AT86RF2XX_REG__RF_CTRL_0);
|
||||
|
||||
/* Clear previous configuration for PHY mode */
|
||||
trx_ctrl2 &= ~(AT86RF2XX_TRX_CTRL_2_MASK__FREQ_MODE);
|
||||
/* Clear previous configuration for GC_TX_OFFS */
|
||||
rf_ctrl0 &= ~AT86RF2XX_RF_CTRL_0_MASK__GC_TX_OFFS;
|
||||
|
||||
if (chan != 0) {
|
||||
/* Set sub mode bit on 915 MHz as recommended by the data sheet */
|
||||
trx_ctrl2 |= AT86RF2XX_TRX_CTRL_2_MASK__SUB_MODE;
|
||||
}
|
||||
|
||||
if (page == 0) {
|
||||
/* BPSK coding */
|
||||
/* Data sheet recommends using a +2 dB setting for BPSK */
|
||||
rf_ctrl0 |= AT86RF2XX_RF_CTRL_0_GC_TX_OFFS__2DB;
|
||||
}
|
||||
else if (page == 2) {
|
||||
/* O-QPSK coding */
|
||||
trx_ctrl2 |= AT86RF2XX_TRX_CTRL_2_MASK__BPSK_OQPSK;
|
||||
/* Data sheet recommends using a +1 dB setting for O-QPSK */
|
||||
rf_ctrl0 |= AT86RF2XX_RF_CTRL_0_GC_TX_OFFS__1DB;
|
||||
}
|
||||
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_CTRL_2, trx_ctrl2);
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__RF_CTRL_0, rf_ctrl0);
|
||||
#endif
|
||||
|
||||
uint8_t phy_cc_cca = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_CC_CCA);
|
||||
/* Clear previous configuration for channel number */
|
||||
phy_cc_cca &= ~(AT86RF2XX_PHY_CC_CCA_MASK__CHANNEL);
|
||||
|
||||
/* Update the channel register */
|
||||
phy_cc_cca |= (chan & AT86RF2XX_PHY_CC_CCA_MASK__CHANNEL);
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__PHY_CC_CCA, phy_cc_cca);
|
||||
|
||||
/* Update the TX power register to achieve the same power (in dBm) */
|
||||
_set_txpower(dev, txpower, chan);
|
||||
|
||||
/* Return to the state we had before reconfiguring */
|
||||
at86rf2xx_set_state(dev, prev_state);
|
||||
}
|
||||
|
||||
|
||||
int8_t at86rf2xx_get_rxsensitivity(const at86rf2xx_t *dev)
|
||||
{
|
||||
uint8_t rxsens = at86rf2xx_reg_read(dev, AT86RF2XX_REG__RX_SYN)
|
||||
@ -413,8 +362,6 @@ void at86rf2xx_set_option(at86rf2xx_t *dev, uint16_t option, bool state)
|
||||
if (state) {
|
||||
DEBUG("[at86rf2xx] opt: enabling CSMA mode" \
|
||||
"(4 retries, min BE: 3 max BE: 5)\n");
|
||||
/* Initialize CSMA seed with hardware address */
|
||||
at86rf2xx_set_csma_seed(dev, dev->netdev.long_addr);
|
||||
at86rf2xx_set_csma_max_retries(dev, 4);
|
||||
at86rf2xx_set_csma_backoff_exp(dev, 3, 5);
|
||||
}
|
||||
|
@ -164,62 +164,6 @@ void at86rf2xx_hardware_reset(at86rf2xx_t *dev)
|
||||
&& (dev->state != AT86RF2XX_STATE_P_ON));
|
||||
}
|
||||
|
||||
void at86rf2xx_configure_phy(at86rf2xx_t *dev)
|
||||
{
|
||||
/* we must be in TRX_OFF before changing the PHY configuration */
|
||||
uint8_t prev_state = at86rf2xx_set_state(dev, AT86RF2XX_STATE_TRX_OFF);
|
||||
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
/* The TX power register must be updated after changing the channel if
|
||||
* moving between bands. */
|
||||
int16_t txpower = at86rf2xx_get_txpower(dev);
|
||||
|
||||
uint8_t trx_ctrl2 = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_CTRL_2);
|
||||
uint8_t rf_ctrl0 = at86rf2xx_reg_read(dev, AT86RF2XX_REG__RF_CTRL_0);
|
||||
|
||||
/* Clear previous configuration for PHY mode */
|
||||
trx_ctrl2 &= ~(AT86RF2XX_TRX_CTRL_2_MASK__FREQ_MODE);
|
||||
/* Clear previous configuration for GC_TX_OFFS */
|
||||
rf_ctrl0 &= ~AT86RF2XX_RF_CTRL_0_MASK__GC_TX_OFFS;
|
||||
|
||||
if (dev->netdev.chan != 0) {
|
||||
/* Set sub mode bit on 915 MHz as recommended by the data sheet */
|
||||
trx_ctrl2 |= AT86RF2XX_TRX_CTRL_2_MASK__SUB_MODE;
|
||||
}
|
||||
|
||||
if (dev->page == 0) {
|
||||
/* BPSK coding */
|
||||
/* Data sheet recommends using a +2 dB setting for BPSK */
|
||||
rf_ctrl0 |= AT86RF2XX_RF_CTRL_0_GC_TX_OFFS__2DB;
|
||||
}
|
||||
else if (dev->page == 2) {
|
||||
/* O-QPSK coding */
|
||||
trx_ctrl2 |= AT86RF2XX_TRX_CTRL_2_MASK__BPSK_OQPSK;
|
||||
/* Data sheet recommends using a +1 dB setting for O-QPSK */
|
||||
rf_ctrl0 |= AT86RF2XX_RF_CTRL_0_GC_TX_OFFS__1DB;
|
||||
}
|
||||
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_CTRL_2, trx_ctrl2);
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__RF_CTRL_0, rf_ctrl0);
|
||||
#endif
|
||||
|
||||
uint8_t phy_cc_cca = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_CC_CCA);
|
||||
/* Clear previous configuration for channel number */
|
||||
phy_cc_cca &= ~(AT86RF2XX_PHY_CC_CCA_MASK__CHANNEL);
|
||||
|
||||
/* Update the channel register */
|
||||
phy_cc_cca |= (dev->netdev.chan & AT86RF2XX_PHY_CC_CCA_MASK__CHANNEL);
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__PHY_CC_CCA, phy_cc_cca);
|
||||
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
/* Update the TX power register to achieve the same power (in dBm) */
|
||||
at86rf2xx_set_txpower(dev, txpower);
|
||||
#endif
|
||||
|
||||
/* Return to the state we had before reconfiguring */
|
||||
at86rf2xx_set_state(dev, prev_state);
|
||||
}
|
||||
|
||||
#if AT86RF2XX_RANDOM_NUMBER_GENERATOR
|
||||
void at86rf2xx_get_random(at86rf2xx_t *dev, uint8_t *data, size_t len)
|
||||
{
|
||||
@ -240,3 +184,22 @@ void at86rf2xx_get_random(at86rf2xx_t *dev, uint8_t *data, size_t len)
|
||||
at86rf2xx_enable_smart_idle(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !AT86RF2XX_IS_PERIPH
|
||||
void at86rf2xx_spi_init(at86rf2xx_t *dev, void (*irq_handler)(void *arg))
|
||||
{
|
||||
/* initialize GPIOs */
|
||||
spi_init_cs(dev->params.spi, dev->params.cs_pin);
|
||||
gpio_init(dev->params.sleep_pin, GPIO_OUT);
|
||||
gpio_clear(dev->params.sleep_pin);
|
||||
gpio_init(dev->params.reset_pin, GPIO_OUT);
|
||||
gpio_set(dev->params.reset_pin);
|
||||
gpio_init_int(dev->params.int_pin, GPIO_IN, GPIO_RISING, irq_handler, dev);
|
||||
|
||||
/* Intentionally check if bus can be acquired, if assertions are on */
|
||||
if (!IS_ACTIVE(NDEBUG)) {
|
||||
spi_acquire(dev->params.spi, dev->params.cs_pin, SPI_MODE_0, dev->params.spi_clk);
|
||||
spi_release(dev->params.spi);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -39,6 +39,9 @@
|
||||
#include "at86rf2xx_netdev.h"
|
||||
#include "at86rf2xx_internal.h"
|
||||
#include "at86rf2xx_registers.h"
|
||||
#if IS_USED(IEEE802154_SECURITY)
|
||||
#include "net/ieee802154_security.h"
|
||||
#endif
|
||||
#if IS_USED(MODULE_AT86RF2XX_AES_SPI)
|
||||
#include "at86rf2xx_aes.h"
|
||||
#endif
|
||||
@ -62,15 +65,85 @@ const netdev_driver_t at86rf2xx_driver = {
|
||||
.set = _set,
|
||||
};
|
||||
|
||||
#if AT86RF2XX_IS_PERIPH
|
||||
#if IS_USED(MODULE_AT86RF2XX_AES_SPI) && \
|
||||
IS_USED(MODULE_IEEE802154_SECURITY)
|
||||
/**
|
||||
* @brief Pass the 802.15.4 encryption key to the transceiver hardware
|
||||
*
|
||||
* @param[in] dev Abstract security device descriptor
|
||||
* @param[in] key Encryption key to be used
|
||||
* @param[in] key_size Size of the encryption key in bytes
|
||||
*/
|
||||
static void _at86rf2xx_set_key(ieee802154_sec_dev_t *dev,
|
||||
const uint8_t *key, uint8_t key_size)
|
||||
{
|
||||
(void)key_size;
|
||||
at86rf2xx_aes_key_write_encrypt((at86rf2xx_t *)dev->ctx, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compute CBC-MAC from IEEE 802.15.4 security context
|
||||
*
|
||||
* @param[in] dev Abstract security device descriptor
|
||||
* @param[out] cipher Buffer to store cipher blocks
|
||||
* @param[in] iv Initial vector
|
||||
* @param[in] plain Input data blocks
|
||||
* @param[in] nblocks Number of blocks
|
||||
*/
|
||||
static void _at86rf2xx_cbc(const ieee802154_sec_dev_t *dev,
|
||||
uint8_t *cipher,
|
||||
uint8_t *iv,
|
||||
const uint8_t *plain,
|
||||
uint8_t nblocks)
|
||||
{
|
||||
at86rf2xx_aes_cbc_encrypt((at86rf2xx_t *)dev->ctx,
|
||||
(aes_block_t *)cipher,
|
||||
NULL,
|
||||
iv,
|
||||
(aes_block_t *)plain,
|
||||
nblocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform ECB encryption
|
||||
*
|
||||
* @param[in] dev Abstract security device descriptor
|
||||
* @param[out] cipher Output cipher blocks
|
||||
* @param[in] plain Plain blocks
|
||||
* @param[in] nblocks Number of blocks
|
||||
*/
|
||||
static void _at86rf2xx_ecb(const ieee802154_sec_dev_t *dev,
|
||||
uint8_t *cipher,
|
||||
const uint8_t *plain,
|
||||
uint8_t nblocks)
|
||||
{
|
||||
at86rf2xx_aes_ecb_encrypt((at86rf2xx_t *)dev->ctx,
|
||||
(aes_block_t *)cipher,
|
||||
NULL,
|
||||
(aes_block_t *)plain,
|
||||
nblocks);
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief Struct that contains IEEE 802.15.4 security operations
|
||||
* which are implemented, using the transceiver´s hardware
|
||||
* crypto capabilities
|
||||
*/
|
||||
static const ieee802154_radio_cipher_ops_t _at86rf2xx_cipher_ops = {
|
||||
.set_key = _at86rf2xx_set_key,
|
||||
.ecb = _at86rf2xx_ecb,
|
||||
.cbc = _at86rf2xx_cbc
|
||||
};
|
||||
#endif /* IS_USED(MODULE_AT86RF2XX_AES_SPI) && \
|
||||
IS_USED(MODULE_IEEE802154_SECURITY) */
|
||||
|
||||
|
||||
/* SOC has radio interrupts, store reference to netdev */
|
||||
static netdev_t *at86rfmega_dev;
|
||||
#else
|
||||
static void _irq_handler(void *arg)
|
||||
{
|
||||
netdev_trigger_event_isr(arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _init(netdev_t *netdev)
|
||||
{
|
||||
@ -78,23 +151,12 @@ static int _init(netdev_t *netdev)
|
||||
netdev_ieee802154_t, netdev);
|
||||
at86rf2xx_t *dev = container_of(netdev_ieee802154, at86rf2xx_t, netdev);
|
||||
|
||||
#if AT86RF2XX_IS_PERIPH
|
||||
at86rfmega_dev = netdev;
|
||||
#else
|
||||
/* initialize GPIOs */
|
||||
spi_init_cs(dev->params.spi, dev->params.cs_pin);
|
||||
gpio_init(dev->params.sleep_pin, GPIO_OUT);
|
||||
gpio_clear(dev->params.sleep_pin);
|
||||
gpio_init(dev->params.reset_pin, GPIO_OUT);
|
||||
gpio_set(dev->params.reset_pin);
|
||||
gpio_init_int(dev->params.int_pin, GPIO_IN, GPIO_RISING, _irq_handler, dev);
|
||||
|
||||
/* Intentionally check if bus can be acquired, if assertions are on */
|
||||
if (!IS_ACTIVE(NDEBUG)) {
|
||||
spi_acquire(dev->params.spi, dev->params.cs_pin, SPI_MODE_0, dev->params.spi_clk);
|
||||
spi_release(dev->params.spi);
|
||||
if (AT86RF2XX_IS_PERIPH) {
|
||||
at86rfmega_dev = netdev;
|
||||
}
|
||||
else {
|
||||
at86rf2xx_spi_init(dev, _irq_handler);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* reset hardware into a defined state */
|
||||
at86rf2xx_hardware_reset(dev);
|
||||
@ -106,8 +168,25 @@ static int _init(netdev_t *netdev)
|
||||
}
|
||||
|
||||
/* reset device to default values and put it into RX state */
|
||||
netdev_ieee802154_reset(&dev->netdev);
|
||||
at86rf2xx_set_addr_long(dev, (eui64_t *)dev->netdev.long_addr);
|
||||
at86rf2xx_set_addr_short(dev, (network_uint16_t *)dev->netdev.short_addr);
|
||||
if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) {
|
||||
static const netopt_enable_t enable = NETOPT_ENABLE;
|
||||
netdev_ieee802154_set(&dev->netdev, NETOPT_ACK_REQ,
|
||||
&enable, sizeof(enable));
|
||||
}
|
||||
#if IS_USED(MODULE_IEEE802154_SECURITY) && \
|
||||
IS_USED(MODULE_AT86RF2XX_AES_SPI)
|
||||
dev->netdev.sec_ctx.dev.cipher_ops = &_at86rf2xx_cipher_ops;
|
||||
dev->netdev.sec_ctx.dev.ctx = dev;
|
||||
#endif
|
||||
|
||||
at86rf2xx_reset(dev);
|
||||
|
||||
/* Initialize CSMA seed with hardware address */
|
||||
at86rf2xx_set_csma_seed(dev, dev->netdev.long_addr);
|
||||
|
||||
/* signal link UP */
|
||||
netdev->event_callback(netdev, NETDEV_EVENT_LINK_UP);
|
||||
|
||||
@ -139,6 +218,9 @@ static int _send(netdev_t *netdev, const iolist_t *iolist)
|
||||
/* send data out directly if pre-loading id disabled */
|
||||
if (!(dev->flags & AT86RF2XX_OPT_PRELOADING)) {
|
||||
at86rf2xx_tx_exec(dev);
|
||||
if (netdev->event_callback) {
|
||||
netdev->event_callback(netdev, NETDEV_EVENT_TX_STARTED);
|
||||
}
|
||||
}
|
||||
/* return the number of bytes that were actually loaded into the frame
|
||||
* buffer/send out */
|
||||
@ -161,11 +243,7 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)
|
||||
at86rf2xx_fb_start(dev);
|
||||
|
||||
/* get the size of the received packet */
|
||||
#if AT86RF2XX_IS_PERIPH
|
||||
phr = TST_RX_LENGTH;
|
||||
#else
|
||||
at86rf2xx_fb_read(dev, &phr, 1);
|
||||
#endif
|
||||
phr = at86rf2xx_get_rx_len(dev);
|
||||
|
||||
/* ignore MSB (refer p.80) and subtract length of FCS field */
|
||||
pkt_len = (phr & 0x7f) - 2;
|
||||
@ -279,10 +357,23 @@ static int _set_state(at86rf2xx_t *dev, netopt_state_t state)
|
||||
}
|
||||
at86rf2xx_set_state(dev, AT86RF2XX_PHY_STATE_TX);
|
||||
at86rf2xx_tx_exec(dev);
|
||||
if (dev->netdev.netdev.event_callback) {
|
||||
dev->netdev.netdev.event_callback(&dev->netdev.netdev, NETDEV_EVENT_TX_STARTED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NETOPT_STATE_RESET:
|
||||
at86rf2xx_hardware_reset(dev);
|
||||
netdev_ieee802154_reset(&dev->netdev);
|
||||
/* set short and long address */
|
||||
at86rf2xx_set_addr_long(dev, (eui64_t *)dev->netdev.long_addr);
|
||||
at86rf2xx_set_addr_short(dev, (network_uint16_t *)dev->netdev.short_addr);
|
||||
|
||||
if (!IS_ACTIVE(AT86RF2XX_BASIC_MODE)) {
|
||||
static const netopt_enable_t enable = NETOPT_ENABLE;
|
||||
netdev_ieee802154_set(&dev->netdev, NETOPT_ACK_REQ,
|
||||
&enable, sizeof(enable));
|
||||
}
|
||||
at86rf2xx_reset(dev);
|
||||
break;
|
||||
default:
|
||||
@ -321,11 +412,13 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len)
|
||||
|
||||
/* getting these options doesn't require the transceiver to be responsive */
|
||||
switch (opt) {
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
case NETOPT_CHANNEL_PAGE:
|
||||
assert(max_len >= sizeof(uint16_t));
|
||||
((uint8_t *)val)[1] = 0;
|
||||
((uint8_t *)val)[0] = at86rf2xx_get_page(dev);
|
||||
((uint8_t *)val)[0] = dev->page;
|
||||
return sizeof(uint16_t);
|
||||
#endif
|
||||
|
||||
case NETOPT_STATE:
|
||||
assert(max_len >= sizeof(netopt_state_t));
|
||||
@ -402,7 +495,7 @@ static int _get(netdev_t *netdev, netopt_t opt, void *val, size_t max_len)
|
||||
switch (opt) {
|
||||
case NETOPT_TX_POWER:
|
||||
assert(max_len >= sizeof(int16_t));
|
||||
*((uint16_t *)val) = at86rf2xx_get_txpower(dev);
|
||||
*((uint16_t *)val) = netdev_ieee802154->txpower;
|
||||
res = sizeof(uint16_t);
|
||||
break;
|
||||
|
||||
@ -502,11 +595,18 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len)
|
||||
switch (opt) {
|
||||
case NETOPT_ADDRESS:
|
||||
assert(len == sizeof(network_uint16_t));
|
||||
memcpy(dev->netdev.short_addr, val, len);
|
||||
#ifdef MODULE_SIXLOWPAN
|
||||
/* https://tools.ietf.org/html/rfc4944#section-12 requires the first bit to
|
||||
* 0 for unicast addresses */
|
||||
dev->netdev.short_addr[0] &= 0x7F;
|
||||
#endif
|
||||
at86rf2xx_set_addr_short(dev, val);
|
||||
/* don't set res to set netdev_ieee802154_t::short_addr */
|
||||
break;
|
||||
case NETOPT_ADDRESS_LONG:
|
||||
assert(len == sizeof(eui64_t));
|
||||
memcpy(dev->netdev.long_addr, val, len);
|
||||
at86rf2xx_set_addr_long(dev, val);
|
||||
/* don't set res to set netdev_ieee802154_t::long_addr */
|
||||
break;
|
||||
@ -526,7 +626,12 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len)
|
||||
res = -EINVAL;
|
||||
break;
|
||||
}
|
||||
at86rf2xx_set_chan(dev, chan);
|
||||
dev->netdev.chan = chan;
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
at86rf2xx_configure_phy(dev, chan, dev->page, dev->netdev.txpower);
|
||||
#else
|
||||
at86rf2xx_configure_phy(dev, chan, 0, dev->netdev.txpower);
|
||||
#endif
|
||||
/* don't set res to set netdev_ieee802154_t::chan */
|
||||
break;
|
||||
|
||||
@ -538,7 +643,8 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len)
|
||||
res = -EINVAL;
|
||||
}
|
||||
else {
|
||||
at86rf2xx_set_page(dev, page);
|
||||
dev->page = page;
|
||||
at86rf2xx_configure_phy(dev, dev->netdev.chan, page, dev->netdev.txpower);
|
||||
res = sizeof(uint16_t);
|
||||
}
|
||||
#else
|
||||
@ -554,7 +660,12 @@ static int _set(netdev_t *netdev, netopt_t opt, const void *val, size_t len)
|
||||
|
||||
case NETOPT_TX_POWER:
|
||||
assert(len <= sizeof(int16_t));
|
||||
at86rf2xx_set_txpower(dev, *((const int16_t *)val));
|
||||
netdev_ieee802154->txpower = *((const int16_t *)val);
|
||||
#if AT86RF2XX_HAVE_SUBGHZ
|
||||
at86rf2xx_configure_phy(dev, dev->netdev.chan, dev->page, *((const int16_t *)val));
|
||||
#else
|
||||
at86rf2xx_configure_phy(dev, dev->netdev.chan, 0, *((const int16_t *)val));
|
||||
#endif
|
||||
res = sizeof(uint16_t);
|
||||
break;
|
||||
|
||||
@ -752,12 +863,7 @@ static void _isr(netdev_t *netdev)
|
||||
}
|
||||
|
||||
/* read (consume) device status */
|
||||
#if AT86RF2XX_IS_PERIPH
|
||||
irq_mask = dev->irq_status;
|
||||
dev->irq_status = 0;
|
||||
#else
|
||||
irq_mask = at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS);
|
||||
#endif
|
||||
irq_mask = at86rf2xx_get_irq_flags(dev);
|
||||
|
||||
trac_status = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_STATE)
|
||||
& AT86RF2XX_TRX_STATE_MASK__TRAC;
|
||||
@ -802,6 +908,32 @@ static void _isr(netdev_t *netdev)
|
||||
}
|
||||
}
|
||||
|
||||
void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params, uint8_t index)
|
||||
{
|
||||
netdev_t *netdev = &dev->netdev.netdev;
|
||||
|
||||
netdev->driver = &at86rf2xx_driver;
|
||||
/* 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 AT86RF2XX_IS_PERIPH
|
||||
(void) params;
|
||||
/* set all interrupts off */
|
||||
at86rf2xx_reg_write(dev, AT86RF2XX_REG__IRQ_MASK, 0x00);
|
||||
#else
|
||||
/* initialize device descriptor */
|
||||
dev->params = *params;
|
||||
#endif
|
||||
|
||||
netdev_register(netdev, NETDEV_AT86RF2XX, index);
|
||||
/* set device address */
|
||||
netdev_ieee802154_setup(&dev->netdev);
|
||||
}
|
||||
|
||||
|
||||
#if AT86RF2XX_IS_PERIPH
|
||||
|
||||
/**
|
||||
|
@ -30,8 +30,8 @@
|
||||
|
||||
#if AT86RF2XX_IS_PERIPH
|
||||
#include <string.h>
|
||||
#include "at86rf2xx_registers.h"
|
||||
#endif
|
||||
#include "at86rf2xx_registers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -220,8 +220,11 @@ void at86rf2xx_hardware_reset(at86rf2xx_t *dev);
|
||||
* @brief Set PHY parameters based on channel and page number
|
||||
*
|
||||
* @param[in,out] dev device to configure
|
||||
* @param[in] chan channel number to be set
|
||||
* @param[in] page channel page
|
||||
* @param[in] txpower TX power in dBm
|
||||
*/
|
||||
void at86rf2xx_configure_phy(at86rf2xx_t *dev);
|
||||
void at86rf2xx_configure_phy(at86rf2xx_t *dev, uint8_t chan, uint8_t page, int16_t txpower);
|
||||
|
||||
#if AT86RF2XX_RANDOM_NUMBER_GENERATOR || defined(DOXYGEN)
|
||||
/**
|
||||
@ -242,6 +245,54 @@ void at86rf2xx_configure_phy(at86rf2xx_t *dev);
|
||||
void at86rf2xx_get_random(at86rf2xx_t *dev, uint8_t *data, size_t len);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize AT86RF2XX SPI communication
|
||||
*
|
||||
* @param[in,out] dev device to initialize
|
||||
* @param[in] irq_handler IRQ handler
|
||||
*/
|
||||
void at86rf2xx_spi_init(at86rf2xx_t *dev, void (*irq_handler)(void *arg));
|
||||
|
||||
/**
|
||||
* @brief Get the PSDU length of the received frame.
|
||||
*
|
||||
* @param[in] dev pointer to the device descriptor
|
||||
*
|
||||
* @return the PSDU length
|
||||
*/
|
||||
static inline uint8_t at86rf2xx_get_rx_len(at86rf2xx_t *dev)
|
||||
{
|
||||
(void) dev;
|
||||
#if AT86RF2XX_IS_PERIPH
|
||||
return TST_RX_LENGTH;
|
||||
#else
|
||||
uint8_t phr;
|
||||
at86rf2xx_fb_read(dev, &phr, 1);
|
||||
return phr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the IRQ flags.
|
||||
*
|
||||
* This function clears the IRQ flags
|
||||
* @param[in,out] dev pointer to the device descriptor
|
||||
*
|
||||
* @return IRQ flags
|
||||
*/
|
||||
static inline uint8_t at86rf2xx_get_irq_flags(at86rf2xx_t *dev)
|
||||
{
|
||||
(void) dev;
|
||||
#if AT86RF2XX_IS_PERIPH
|
||||
uint8_t irq_mask = dev->irq_status;
|
||||
dev->irq_status = 0;
|
||||
return irq_mask;
|
||||
#else
|
||||
return at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -68,6 +68,7 @@ extern "C" {
|
||||
#define AT86RF2XX_MIN_CHANNEL (IEEE802154_CHANNEL_MIN)
|
||||
#define AT86RF2XX_MAX_CHANNEL (IEEE802154_CHANNEL_MAX)
|
||||
#define AT86RF2XX_DEFAULT_CHANNEL (CONFIG_IEEE802154_DEFAULT_CHANNEL)
|
||||
#define AT86RF2XX_DEFAULT_PAGE (0)
|
||||
/* Only page 0 is supported in the 2.4 GHz band */
|
||||
#endif
|
||||
/** @} */
|
||||
@ -328,16 +329,6 @@ void at86rf2xx_setup(at86rf2xx_t *dev, const at86rf2xx_params_t *params, uint8_t
|
||||
*/
|
||||
void at86rf2xx_reset(at86rf2xx_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Get the short address of the given device
|
||||
*
|
||||
* @param[in] dev device to read from
|
||||
* @param[out] addr the short address will be stored here
|
||||
*
|
||||
* @return the currently set (2-byte) short address
|
||||
*/
|
||||
void at86rf2xx_get_addr_short(const at86rf2xx_t *dev, network_uint16_t *addr);
|
||||
|
||||
/**
|
||||
* @brief Set the short address of the given device
|
||||
*
|
||||
@ -346,16 +337,6 @@ void at86rf2xx_get_addr_short(const at86rf2xx_t *dev, network_uint16_t *addr);
|
||||
*/
|
||||
void at86rf2xx_set_addr_short(at86rf2xx_t *dev, const network_uint16_t *addr);
|
||||
|
||||
/**
|
||||
* @brief Get the configured long address of the given device
|
||||
*
|
||||
* @param[in] dev device to read from
|
||||
* @param[out] addr the long address will be stored here
|
||||
*
|
||||
* @return the currently set (8-byte) long address
|
||||
*/
|
||||
void at86rf2xx_get_addr_long(const at86rf2xx_t *dev, eui64_t *addr);
|
||||
|
||||
/**
|
||||
* @brief Set the long address of the given device
|
||||
*
|
||||
@ -364,40 +345,6 @@ void at86rf2xx_get_addr_long(const at86rf2xx_t *dev, eui64_t *addr);
|
||||
*/
|
||||
void at86rf2xx_set_addr_long(at86rf2xx_t *dev, const eui64_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(const at86rf2xx_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 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(const at86rf2xx_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set the channel page of the given device
|
||||
*
|
||||
* @param[in,out] 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 PHY mode of the given device
|
||||
*
|
||||
@ -431,15 +378,6 @@ uint8_t at86rf2xx_get_rate(at86rf2xx_t *dev);
|
||||
*/
|
||||
int at86rf2xx_set_rate(at86rf2xx_t *dev, uint8_t rate);
|
||||
|
||||
/**
|
||||
* @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(const at86rf2xx_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set the PAN ID of the given device
|
||||
*
|
||||
@ -448,15 +386,6 @@ uint16_t at86rf2xx_get_pan(const at86rf2xx_t *dev);
|
||||
*/
|
||||
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(const at86rf2xx_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set the transmission power of the given device [in dBm]
|
||||
*
|
||||
@ -467,8 +396,9 @@ int16_t at86rf2xx_get_txpower(const at86rf2xx_t *dev);
|
||||
*
|
||||
* @param[in] dev device to write to
|
||||
* @param[in] txpower transmission power in dBm
|
||||
* @param[in] channel the current channel
|
||||
*/
|
||||
void at86rf2xx_set_txpower(const at86rf2xx_t *dev, int16_t txpower);
|
||||
void at86rf2xx_set_txpower(const at86rf2xx_t *dev, int16_t txpower, uint8_t channel);
|
||||
|
||||
/**
|
||||
* @brief Get the configured receiver sensitivity of the given device [in dBm]
|
||||
@ -601,20 +531,6 @@ void at86rf2xx_set_option(at86rf2xx_t *dev, uint16_t option, bool state);
|
||||
*/
|
||||
uint8_t at86rf2xx_set_state(at86rf2xx_t *dev, uint8_t state);
|
||||
|
||||
/**
|
||||
* @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 0 on error
|
||||
*/
|
||||
size_t at86rf2xx_send(at86rf2xx_t *dev, const uint8_t *data, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Prepare for sending of data
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user