ieee802154/radio_hal: detach hal descriptor from driver

This commit is contained in:
Jose Alamos 2021-06-07 13:35:18 +02:00
parent c1d28d69a7
commit ddc9c7c686
No known key found for this signature in database
GPG Key ID: F483EB800EF89DD9
21 changed files with 274 additions and 242 deletions

View File

@ -30,9 +30,6 @@
#include "kernel_defines.h" #include "kernel_defines.h"
#include "net/ieee802154/radio.h" #include "net/ieee802154/radio.h"
#if IS_USED(MODULE_NETDEV_IEEE802154_SUBMAC)
#include "net/netdev/ieee802154_submac.h"
#endif
#include "net/netopt.h" #include "net/netopt.h"
@ -285,17 +282,20 @@ enum {
/** /**
* @brief Device descriptor for CC2538 transceiver * @brief Device descriptor for CC2538 transceiver
*
* @extends netdev_ieee802154_t if using legacy radio
* @extends netdev_ieee802154_submac_t if using radio HAL
*/ */
typedef struct { typedef struct {
#if IS_USED(MODULE_NETDEV_IEEE802154_SUBMAC)
netdev_ieee802154_submac_t netdev; /**< netdev parent struct */
#endif
uint8_t state; /**< current state of the radio */ uint8_t state; /**< current state of the radio */
} cc2538_rf_t; } cc2538_rf_t;
/**
* @brief Setup CC2538 in order to be used with the IEEE 802.15.4 Radio HAL
*
* @note This functions MUST be called before @ref cc2538_init.
*
* @param[in] hal pointer to the HAL descriptor associated to the device.
*/
void cc2538_rf_hal_setup(ieee802154_dev_t *hal);
/** /**
* @brief IRQ handler for RF events * @brief IRQ handler for RF events
* *
@ -380,7 +380,7 @@ void cc2538_off(void);
bool cc2538_on(void); bool cc2538_on(void);
/** /**
* @brief Setup a CC2538 radio device for use with netdev * @brief Setup a CC2538 radio device
* *
* @param[out] dev Device descriptor * @param[out] dev Device descriptor
*/ */

View File

@ -1,39 +0,0 @@
/*
* Copyright (C) 2016 MUTEX NZ Ltd
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
*/
/**
* @ingroup cpu_cc2538
* @{
*
* @file
* @brief Netdev interface to CC2538 radio driver
*
* @author Aaron Sowry <aaron@mutex.nz>
*/
#ifndef CC2538_RF_NETDEV_H
#define CC2538_RF_NETDEV_H
#include "net/netdev.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Reference to the netdev device driver struct
*/
extern const netdev_driver_t cc2538_rf_driver;
#ifdef __cplusplus
}
#endif
#endif /* CC2538_RF_NETDEV_H */
/** @} */

View File

@ -23,7 +23,6 @@
#include "periph_conf.h" #include "periph_conf.h"
#include "cc2538_rf.h" #include "cc2538_rf.h"
#include "cc2538_rf_netdev.h"
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
#include "debug.h" #include "debug.h"
@ -211,10 +210,5 @@ bool cc2538_on(void)
void cc2538_setup(cc2538_rf_t *dev) void cc2538_setup(cc2538_rf_t *dev)
{ {
(void) dev; (void) dev;
#if IS_USED(MODULE_NETDEV_IEEE802154_SUBMAC)
extern ieee802154_dev_t cc2538_rf_dev;
netdev_register(&dev->netdev.dev.netdev, NETDEV_CC2538, 0);
netdev_ieee802154_submac_init(&dev->netdev, &cc2538_rf_dev);
#endif
cc2538_init(); cc2538_init();
} }

View File

@ -22,7 +22,6 @@
#include "cpu.h" #include "cpu.h"
#include "cc2538.h" #include "cc2538.h"
#include "cc2538_rf.h" #include "cc2538_rf.h"
#include "cc2538_rf_netdev.h"
#include "cc2538_rf_internal.h" #include "cc2538_rf_internal.h"
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0

View File

@ -32,9 +32,7 @@
static const ieee802154_radio_ops_t cc2538_rf_ops; static const ieee802154_radio_ops_t cc2538_rf_ops;
ieee802154_dev_t cc2538_rf_dev = { static ieee802154_dev_t *cc2538_rf_hal;
.driver = &cc2538_rf_ops,
};
static bool cc2538_tx_busy; /**< used to indicate TX chain is busy */ static bool cc2538_tx_busy; /**< used to indicate TX chain is busy */
static bool cc2538_rx_busy; /**< used to indicate RX chain is busy */ static bool cc2538_rx_busy; /**< used to indicate RX chain is busy */
@ -332,21 +330,21 @@ void cc2538_irq_handler(void)
if ((flags_f0 & SFD)) { if ((flags_f0 & SFD)) {
/* If the radio already transmitted, this SFD is the TX_START event */ /* If the radio already transmitted, this SFD is the TX_START event */
if (cc2538_tx_busy) { if (cc2538_tx_busy) {
cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_INDICATION_TX_START); cc2538_rf_hal->cb(cc2538_rf_hal, IEEE802154_RADIO_INDICATION_TX_START);
} }
/* If the RX chain was not busy, the detected SFD corresponds to a new /* If the RX chain was not busy, the detected SFD corresponds to a new
* incoming frame. Note the automatic ACK frame also triggers this event. * incoming frame. Note the automatic ACK frame also triggers this event.
* Therefore, we use this variable to distinguish them. */ * Therefore, we use this variable to distinguish them. */
else if (!cc2538_rx_busy){ else if (!cc2538_rx_busy){
cc2538_rx_busy = true; cc2538_rx_busy = true;
cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_INDICATION_RX_START); cc2538_rf_hal->cb(cc2538_rf_hal, IEEE802154_RADIO_INDICATION_RX_START);
} }
} }
if (flags_f1 & TXDONE) { if (flags_f1 & TXDONE) {
/* TXDONE marks the end of the TX chain. The radio is not busy anymore */ /* TXDONE marks the end of the TX chain. The radio is not busy anymore */
cc2538_tx_busy = false; cc2538_tx_busy = false;
cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_CONFIRM_TX_DONE); cc2538_rf_hal->cb(cc2538_rf_hal, IEEE802154_RADIO_CONFIRM_TX_DONE);
} }
if (flags_f0 & RXPKTDONE) { if (flags_f0 & RXPKTDONE) {
@ -363,14 +361,14 @@ void cc2538_irq_handler(void)
*/ */
cc2538_rx_busy = false; cc2538_rx_busy = false;
} }
cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_INDICATION_RX_DONE); cc2538_rf_hal->cb(cc2538_rf_hal, IEEE802154_RADIO_INDICATION_RX_DONE);
} }
else { else {
/* Disable RX while the frame has not been processed */ /* Disable RX while the frame has not been processed */
RFCORE_XREG_RXMASKCLR = 0xFF; RFCORE_XREG_RXMASKCLR = 0xFF;
/* CRC failed; discard packet. The RX chain is not busy anymore */ /* CRC failed; discard packet. The RX chain is not busy anymore */
cc2538_rx_busy = false; cc2538_rx_busy = false;
cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_INDICATION_CRC_ERROR); cc2538_rf_hal->cb(cc2538_rf_hal, IEEE802154_RADIO_INDICATION_CRC_ERROR);
} }
} }
@ -392,13 +390,13 @@ void cc2538_irq_handler(void)
else { else {
/* In case of CCA failure the TX chain is not busy anymore */ /* In case of CCA failure the TX chain is not busy anymore */
cc2538_tx_busy = false; cc2538_tx_busy = false;
cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_CONFIRM_TX_DONE); cc2538_rf_hal->cb(cc2538_rf_hal, IEEE802154_RADIO_CONFIRM_TX_DONE);
} }
} }
else { else {
cc2538_cca_status = BOOLEAN(RFCORE->XREG_FSMSTAT1bits.CCA) cc2538_cca_status = BOOLEAN(RFCORE->XREG_FSMSTAT1bits.CCA)
&& RFCORE->XREG_RSSISTATbits.RSSI_VALID; && RFCORE->XREG_RSSISTATbits.RSSI_VALID;
cc2538_rf_dev.cb(&cc2538_rf_dev, IEEE802154_RADIO_CONFIRM_CCA); cc2538_rf_hal->cb(cc2538_rf_hal, IEEE802154_RADIO_CONFIRM_CCA);
} }
} }
} }
@ -536,6 +534,15 @@ static int _set_frame_filter_mode(ieee802154_dev_t *dev, ieee802154_filter_mode_
return 0; return 0;
} }
void cc2538_rf_hal_setup(ieee802154_dev_t *hal)
{
/* We don't set hal->priv because the context of this device is global */
/* We need to store a reference to the HAL descriptor though for the ISR */
hal->driver = &cc2538_rf_ops;
cc2538_rf_hal = hal;
}
static const ieee802154_radio_ops_t cc2538_rf_ops = { static const ieee802154_radio_ops_t cc2538_rf_ops = {
.caps = IEEE802154_CAP_24_GHZ .caps = IEEE802154_CAP_24_GHZ
| IEEE802154_CAP_AUTO_CSMA | IEEE802154_CAP_AUTO_CSMA

View File

@ -37,9 +37,6 @@
#define NRF802154_H #define NRF802154_H
#include "net/ieee802154/radio.h" #include "net/ieee802154/radio.h"
#if IS_USED(MODULE_NETDEV_IEEE802154_SUBMAC)
#include "net/netdev/ieee802154_submac.h"
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -47,15 +44,8 @@ extern "C" {
/** /**
* @brief Device descriptor for NRF802154 transceiver * @brief Device descriptor for NRF802154 transceiver
*
* @extends netdev_ieee802154_t if using legacy radio
* @extends netdev_ieee802154_submac_t if using radio HAL
*/ */
typedef struct { typedef struct nrf802154 nrf802154_t;
#if IS_USED(MODULE_NETDEV_IEEE802154_SUBMAC)
netdev_ieee802154_submac_t netdev; /**< netdev SubMAC descriptor */
#endif
} nrf802154_t;
/** /**
* @defgroup drivers_nrf52_802154_conf nrf802154 driver compile configuration * @defgroup drivers_nrf52_802154_conf nrf802154 driver compile configuration
@ -84,6 +74,15 @@ typedef struct {
#define NRF802154_TIMER TIMER_DEV(1) #define NRF802154_TIMER TIMER_DEV(1)
#endif #endif
/**
* @brief Setup NRF802154 in order to be used with the IEEE 802.15.4 Radio HAL
*
* @note This functions MUST be called before @ref nrf802154_init.
*
* @param[in] hal pointer to the HAL descriptor associated to the device.
*/
void nrf802154_hal_setup(ieee802154_dev_t *hal);
/** /**
* @brief Initialize the NRF52840 radio. * @brief Initialize the NRF52840 radio.
* *
@ -93,7 +92,7 @@ typedef struct {
int nrf802154_init(void); int nrf802154_init(void);
/** /**
* @brief Setup a NRF802154 radio device for use with netdev * @brief Setup a NRF802154 radio device
* *
* @param[out] dev Device descriptor * @param[out] dev Device descriptor
*/ */

View File

@ -98,10 +98,7 @@ static struct {
}; };
static const ieee802154_radio_ops_t nrf802154_ops; static const ieee802154_radio_ops_t nrf802154_ops;
static ieee802154_dev_t *nrf802154_hal_dev;
ieee802154_dev_t nrf802154_hal_dev = {
.driver = &nrf802154_ops,
};
static void _power_on(void) static void _power_on(void)
{ {
@ -428,7 +425,7 @@ static int _request_set_trx_state(ieee802154_dev_t *dev, ieee802154_trx_state_t
static void _timer_cb(void *arg, int chan) static void _timer_cb(void *arg, int chan)
{ {
(void)arg; (void)arg;
ieee802154_dev_t *dev = &nrf802154_hal_dev; ieee802154_dev_t *dev = nrf802154_hal_dev;
if (chan == MAC_TIMER_CHAN_ACK) { if (chan == MAC_TIMER_CHAN_ACK) {
/* Copy sqn */ /* Copy sqn */
@ -477,7 +474,7 @@ int nrf802154_init(void)
void isr_radio(void) void isr_radio(void)
{ {
ieee802154_dev_t *dev = &nrf802154_hal_dev; ieee802154_dev_t *dev = nrf802154_hal_dev;
if (NRF_RADIO->EVENTS_FRAMESTART) { if (NRF_RADIO->EVENTS_FRAMESTART) {
NRF_RADIO->EVENTS_FRAMESTART = 0; NRF_RADIO->EVENTS_FRAMESTART = 0;
@ -783,17 +780,17 @@ static int _set_csma_params(ieee802154_dev_t *dev, const ieee802154_csma_be_t *b
void nrf802154_setup(nrf802154_t *dev) void nrf802154_setup(nrf802154_t *dev)
{ {
(void) dev; (void) dev;
#if IS_USED(MODULE_NETDEV_IEEE802154_SUBMAC)
netdev_ieee802154_submac_t *netdev_submac = &dev->netdev;
netdev_ieee802154_t *netdev_ieee802154 = &netdev_submac->dev;
netdev_t *netdev = &netdev_ieee802154->netdev;
netdev_register(netdev, NETDEV_NRF802154, 0);
DEBUG("[nrf802154] init submac.\n")
netdev_ieee802154_submac_init(&dev->netdev, &nrf802154_hal_dev);
#endif
nrf802154_init(); nrf802154_init();
} }
void nrf802154_hal_setup(ieee802154_dev_t *hal)
{
/* We don't set hal->priv because the context of this device is global */
/* We need to store a reference to the HAL descriptor though for the ISR */
hal->driver = &nrf802154_ops;
nrf802154_hal_dev = hal;
}
static const ieee802154_radio_ops_t nrf802154_ops = { static const ieee802154_radio_ops_t nrf802154_ops = {
.caps = IEEE802154_CAP_24_GHZ .caps = IEEE802154_CAP_24_GHZ
| IEEE802154_CAP_IRQ_CRC_ERROR | IEEE802154_CAP_IRQ_CRC_ERROR

View File

@ -57,13 +57,12 @@ typedef struct {
* @brief Init the IEEE 802.15.4 SubMAC netdev adoption. * @brief Init the IEEE 802.15.4 SubMAC netdev adoption.
* *
* @param[in] netdev_submac pointer to the netdev submac descriptor. * @param[in] netdev_submac pointer to the netdev submac descriptor.
* @param[in] dev pointer to the device associated to @p netdev_submac.
* *
* @return 0 on success. * @return 0 on success.
* @return negative errno on failure. * @return negative errno on failure.
*/ */
int netdev_ieee802154_submac_init(netdev_ieee802154_submac_t *netdev_submac, int netdev_ieee802154_submac_init(netdev_ieee802154_submac_t *netdev_submac);
ieee802154_dev_t *dev);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -273,7 +273,7 @@ static const ieee802154_submac_cb_t _cb = {
/* Event Notification callback */ /* Event Notification callback */
static void _hal_radio_cb(ieee802154_dev_t *dev, ieee802154_trx_ev_t status) static void _hal_radio_cb(ieee802154_dev_t *dev, ieee802154_trx_ev_t status)
{ {
ieee802154_submac_t *submac = dev->ctx; ieee802154_submac_t *submac = container_of(dev, ieee802154_submac_t, dev);
netdev_ieee802154_submac_t *netdev_submac = container_of(submac, netdev_ieee802154_submac_t *netdev_submac = container_of(submac,
netdev_ieee802154_submac_t, netdev_ieee802154_submac_t,
submac); submac);
@ -329,20 +329,17 @@ static int _init(netdev_t *netdev)
return 0; return 0;
} }
int netdev_ieee802154_submac_init(netdev_ieee802154_submac_t *netdev_submac, int netdev_ieee802154_submac_init(netdev_ieee802154_submac_t *netdev_submac)
ieee802154_dev_t *dev)
{ {
netdev_t *netdev = &netdev_submac->dev.netdev; netdev_t *netdev = &netdev_submac->dev.netdev;
netdev->driver = &netdev_submac_driver; netdev->driver = &netdev_submac_driver;
ieee802154_submac_t *submac = &netdev_submac->submac; ieee802154_submac_t *submac = &netdev_submac->submac;
submac->dev = dev;
submac->cb = &_cb; submac->cb = &_cb;
submac->dev->ctx = submac;
/* Set the Event Notification */ /* Set the Event Notification */
submac->dev->cb = _hal_radio_cb; submac->dev.cb = _hal_radio_cb;
netdev_submac->ack_timer.callback = _ack_timeout; netdev_submac->ack_timer.callback = _ack_timeout;
netdev_submac->ack_timer.arg = netdev_submac; netdev_submac->ack_timer.arg = netdev_submac;

View File

@ -71,6 +71,10 @@
#include "nrf802154.h" #include "nrf802154.h"
#endif #endif
#if IS_USED(MODULE_NETDEV_IEEE802154_SUBMAC)
#include "net/netdev/ieee802154_submac.h"
#endif
#include "lwip.h" #include "lwip.h"
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
@ -170,7 +174,7 @@ extern void stm32_eth_netdev_setup(netdev_t *netdev);
#endif #endif
#ifdef MODULE_NRF802154 #ifdef MODULE_NRF802154
static nrf802154_t nrf802154_dev; static netdev_ieee802154_submac_t nrf802154_netdev;
#endif #endif
void lwip_bootstrap(void) void lwip_bootstrap(void)
@ -263,8 +267,12 @@ void lwip_bootstrap(void)
return; return;
} }
#elif defined(MODULE_NRF802154) #elif defined(MODULE_NRF802154)
nrf802154_setup(&nrf802154_dev); netdev_register(&nrf802154_netdev.dev.netdev, NETDEV_NRF802154, 0);
if (netif_add_noaddr(&netif[0], &nrf802154_dev.netdev.dev.netdev, lwip_netdev_init, netdev_ieee802154_submac_init(&nrf802154_netdev);
nrf802154_hal_setup(&nrf802154_netdev.submac.dev);
nrf802154_init();
if (netif_add_noaddr(&netif[0], &nrf802154_netdev.dev.netdev, lwip_netdev_init,
tcpip_6lowpan_input) == NULL) { tcpip_6lowpan_input) == NULL) {
DEBUG("Could not add nrf802154 device\n"); DEBUG("Could not add nrf802154 device\n");
return; return;

View File

@ -40,6 +40,10 @@
#include "nrf802154.h" #include "nrf802154.h"
#endif #endif
#if IS_USED(MODULE_NETDEV_IEEE802154_SUBMAC)
#include "net/netdev/ieee802154_submac.h"
#endif
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
#include "debug.h" #include "debug.h"
@ -52,7 +56,7 @@
#endif #endif
#ifdef MODULE_CC2538_RF #ifdef MODULE_CC2538_RF
static cc2538_rf_t cc2538_rf_dev; static netdev_ieee802154_submac_t cc2538_rf_netdev;
#endif #endif
#ifdef MODULE_AT86RF2XX #ifdef MODULE_AT86RF2XX
@ -64,7 +68,7 @@ static kw41zrf_t kw41z_dev;
#endif #endif
#ifdef MODULE_NRF802154 #ifdef MODULE_NRF802154
static nrf802154_t nrf802154_dev; static netdev_ieee802154_submac_t nrf802154_netdev;
#endif #endif
static uint8_t rx_buf[OPENTHREAD_NETDEV_BUFLEN]; static uint8_t rx_buf[OPENTHREAD_NETDEV_BUFLEN];
@ -83,12 +87,18 @@ void openthread_bootstrap(void)
netdev_t *netdev = &kw41z_dev.netdev.netdev; netdev_t *netdev = &kw41z_dev.netdev.netdev;
#endif #endif
#ifdef MODULE_CC2538_RF #ifdef MODULE_CC2538_RF
cc2538_setup(&cc2538_rf_dev); netdev_register(&cc2538_rf_netdev.dev.netdev, NETDEV_CC2538, 0);
netdev_t *netdev = &cc2538_rf_dev.netdev.dev.netdev; netdev_ieee802154_submac_init(&cc2538_rf_netdev);
cc2538_rf_hal_setup(&cc2538_rf_netdev.submac.dev);
cc2538_init();
netdev_t *netdev = &cc2538_rf_netdev.dev.netdev;
#endif #endif
#ifdef MODULE_NRF802154 #ifdef MODULE_NRF802154
nrf802154_setup(&nrf802154_dev); netdev_register(&nrf802154_netdev.dev.netdev, NETDEV_NRF802154, 0);
netdev_t *netdev = &nrf802154_dev.netdev.dev.netdev; netdev_ieee802154_submac_init(&nrf802154_netdev);
nrf802154_hal_setup(&nrf802154_netdev.submac.dev);
nrf802154_init();
netdev_t *netdev = &nrf802154_netdev.dev.netdev;
#endif #endif
openthread_radio_init(netdev, tx_buf, rx_buf); openthread_radio_init(netdev, tx_buf, rx_buf);

View File

@ -48,6 +48,13 @@
#ifdef MODULE_AT86RF2XX #ifdef MODULE_AT86RF2XX
static at86rf2xx_t at86rf2xx_dev; static at86rf2xx_t at86rf2xx_dev;
#endif #endif
#else
#ifdef MODULE_CC2538_RF
static ieee802154_dev_t cc2538_rf_dev;
#endif
#ifdef MODULE_NRF802154
static ieee802154_dev_t nrf802154_hal_dev;
#endif
#endif #endif
static char _stack[OPENWSN_SCHED_STACKSIZE]; static char _stack[OPENWSN_SCHED_STACKSIZE];
@ -73,13 +80,13 @@ void* _radio_init_dev(void)
#endif #endif
#else #else
#ifdef MODULE_CC2538_RF #ifdef MODULE_CC2538_RF
extern ieee802154_dev_t cc2538_rf_dev;
dev = &cc2538_rf_dev; dev = &cc2538_rf_dev;
cc2538_rf_hal_setup(dev);
cc2538_init(); cc2538_init();
#endif #endif
#ifdef MODULE_NRF802154 #ifdef MODULE_NRF802154
extern ieee802154_dev_t nrf802154_hal_dev;
dev = &nrf802154_hal_dev; dev = &nrf802154_hal_dev;
nrf802154_hal_setup(dev);
nrf802154_init(); nrf802154_init();
#endif #endif
#endif #endif

View File

@ -431,9 +431,9 @@ struct ieee802154_dev {
*/ */
const ieee802154_radio_ops_t *driver; const ieee802154_radio_ops_t *driver;
/** /**
* @brief pointer to the context of the device * @brief pointer to the private descriptor of the device
*/ */
void *ctx; void *priv;
/** /**
* @brief the event callback of the device * @brief the event callback of the device
*/ */

View File

@ -104,9 +104,9 @@ typedef struct {
* @brief IEEE 802.15.4 SubMAC descriptor * @brief IEEE 802.15.4 SubMAC descriptor
*/ */
struct ieee802154_submac { struct ieee802154_submac {
ieee802154_dev_t dev; /**< 802.15.4 HAL descriptor */
eui64_t ext_addr; /**< IEEE 802.15.4 extended address */ eui64_t ext_addr; /**< IEEE 802.15.4 extended address */
network_uint16_t short_addr; /**< IEEE 802.15.4 short address */ network_uint16_t short_addr; /**< IEEE 802.15.4 short address */
ieee802154_dev_t *dev; /**< pointer to the 802.15.4 HAL descriptor */
const ieee802154_submac_cb_t *cb; /**< pointer to the SubMAC callbacks */ const ieee802154_submac_cb_t *cb; /**< pointer to the SubMAC callbacks */
ieee802154_csma_be_t be; /**< CSMA-CA backoff exponent params */ ieee802154_csma_be_t be; /**< CSMA-CA backoff exponent params */
bool wait_for_ack; /**< SubMAC is waiting for an ACK frame */ bool wait_for_ack; /**< SubMAC is waiting for an ACK frame */
@ -173,8 +173,9 @@ int ieee802154_send(ieee802154_submac_t *submac, const iolist_t *iolist);
static inline int ieee802154_set_short_addr(ieee802154_submac_t *submac, static inline int ieee802154_set_short_addr(ieee802154_submac_t *submac,
const network_uint16_t *short_addr) const network_uint16_t *short_addr)
{ {
int res = ieee802154_radio_config_addr_filter(&submac->dev,
int res = ieee802154_radio_config_addr_filter(submac->dev, IEEE802154_AF_SHORT_ADDR, short_addr); IEEE802154_AF_SHORT_ADDR,
short_addr);
if (res >= 0) { if (res >= 0) {
memcpy(&submac->short_addr, short_addr, IEEE802154_SHORT_ADDRESS_LEN); memcpy(&submac->short_addr, short_addr, IEEE802154_SHORT_ADDRESS_LEN);
@ -195,7 +196,9 @@ static inline int ieee802154_set_short_addr(ieee802154_submac_t *submac,
static inline int ieee802154_set_ext_addr(ieee802154_submac_t *submac, static inline int ieee802154_set_ext_addr(ieee802154_submac_t *submac,
const eui64_t *ext_addr) const eui64_t *ext_addr)
{ {
int res = ieee802154_radio_config_addr_filter(submac->dev, IEEE802154_AF_EXT_ADDR, ext_addr); int res = ieee802154_radio_config_addr_filter(&submac->dev,
IEEE802154_AF_EXT_ADDR,
ext_addr);
if (res >= 0) { if (res >= 0) {
memcpy(&submac->ext_addr, ext_addr, IEEE802154_LONG_ADDRESS_LEN); memcpy(&submac->ext_addr, ext_addr, IEEE802154_LONG_ADDRESS_LEN);
@ -215,7 +218,9 @@ static inline int ieee802154_set_ext_addr(ieee802154_submac_t *submac,
static inline int ieee802154_set_panid(ieee802154_submac_t *submac, static inline int ieee802154_set_panid(ieee802154_submac_t *submac,
const uint16_t *panid) const uint16_t *panid)
{ {
int res = ieee802154_radio_config_addr_filter(submac->dev, IEEE802154_AF_PANID, panid); int res = ieee802154_radio_config_addr_filter(&submac->dev,
IEEE802154_AF_PANID,
panid);
if (res >= 0) { if (res >= 0) {
submac->panid = *panid; submac->panid = *panid;
@ -318,7 +323,7 @@ static inline int ieee802154_set_tx_power(ieee802154_submac_t *submac,
*/ */
static inline int ieee802154_get_frame_length(ieee802154_submac_t *submac) static inline int ieee802154_get_frame_length(ieee802154_submac_t *submac)
{ {
return ieee802154_radio_len(submac->dev); return ieee802154_radio_len(&submac->dev);
} }
/** /**
@ -337,7 +342,7 @@ static inline int ieee802154_get_frame_length(ieee802154_submac_t *submac)
static inline int ieee802154_read_frame(ieee802154_submac_t *submac, void *buf, static inline int ieee802154_read_frame(ieee802154_submac_t *submac, void *buf,
size_t len, ieee802154_rx_info_t *info) size_t len, ieee802154_rx_info_t *info)
{ {
return ieee802154_radio_read(submac->dev, buf, len, info); return ieee802154_radio_read(&submac->dev, buf, len, info);
} }
/** /**

View File

@ -22,6 +22,7 @@
#include "include/init_devs.h" #include "include/init_devs.h"
#include "cc2538_rf.h" #include "cc2538_rf.h"
#include "net/netdev/ieee802154_submac.h"
/** /**
* @brief Define stack parameters for the MAC layer thread * @brief Define stack parameters for the MAC layer thread
@ -32,7 +33,7 @@
#define CC2538_MAC_PRIO (GNRC_NETIF_PRIO) #define CC2538_MAC_PRIO (GNRC_NETIF_PRIO)
#endif #endif
static cc2538_rf_t cc2538_rf_dev; static netdev_ieee802154_submac_t cc2538_rf_netdev;
static char _cc2538_rf_stack[CC2538_MAC_STACKSIZE]; static char _cc2538_rf_stack[CC2538_MAC_STACKSIZE];
static gnrc_netif_t _netif; static gnrc_netif_t _netif;
@ -40,10 +41,14 @@ void auto_init_cc2538_rf(void)
{ {
LOG_DEBUG("[auto_init_netif] initializing cc2538 radio\n"); LOG_DEBUG("[auto_init_netif] initializing cc2538 radio\n");
cc2538_setup(&cc2538_rf_dev); netdev_register(&cc2538_rf_netdev.dev.netdev, NETDEV_CC2538, 0);
netdev_ieee802154_submac_init(&cc2538_rf_netdev);
cc2538_rf_hal_setup(&cc2538_rf_netdev.submac.dev);
cc2538_init();
gnrc_netif_ieee802154_create(&_netif, _cc2538_rf_stack, gnrc_netif_ieee802154_create(&_netif, _cc2538_rf_stack,
CC2538_MAC_STACKSIZE, CC2538_MAC_STACKSIZE,
CC2538_MAC_PRIO, "cc2538_rf", CC2538_MAC_PRIO, "cc2538_rf",
&cc2538_rf_dev.netdev.dev.netdev); &cc2538_rf_netdev.dev.netdev);
} }
/** @} */ /** @} */

View File

@ -22,6 +22,7 @@
#include "nrf802154.h" #include "nrf802154.h"
#include "net/gnrc/netif/ieee802154.h" #include "net/gnrc/netif/ieee802154.h"
#include "include/init_devs.h" #include "include/init_devs.h"
#include "net/netdev/ieee802154_submac.h"
/** /**
* @brief Define stack parameters for the MAC layer thread * @brief Define stack parameters for the MAC layer thread
@ -38,16 +39,20 @@
static char _stack[NRF802154_MAC_STACKSIZE]; static char _stack[NRF802154_MAC_STACKSIZE];
static gnrc_netif_t _netif; static gnrc_netif_t _netif;
static nrf802154_t nrf802154_dev; static netdev_ieee802154_submac_t nrf802154_netdev;
void auto_init_nrf802154(void) void auto_init_nrf802154(void)
{ {
LOG_DEBUG("[auto_init_netif] initializing nrf802154\n"); LOG_DEBUG("[auto_init_netif] initializing nrf802154\n");
nrf802154_setup(&nrf802154_dev); netdev_register(&nrf802154_netdev.dev.netdev, NETDEV_NRF802154, 0);
netdev_ieee802154_submac_init(&nrf802154_netdev);
nrf802154_hal_setup(&nrf802154_netdev.submac.dev);
nrf802154_init();
gnrc_netif_ieee802154_create(&_netif, _stack, gnrc_netif_ieee802154_create(&_netif, _stack,
NRF802154_MAC_STACKSIZE, NRF802154_MAC_STACKSIZE,
NRF802154_MAC_PRIO, "nrf802154", NRF802154_MAC_PRIO, "nrf802154",
&nrf802154_dev.netdev.dev.netdev); &nrf802154_netdev.dev.netdev);
} }
/** @} */ /** @} */

View File

@ -48,7 +48,7 @@ static inline void _req_set_trx_state_wait_busy(ieee802154_dev_t *dev,
static void _tx_end(ieee802154_submac_t *submac, int status, static void _tx_end(ieee802154_submac_t *submac, int status,
ieee802154_tx_info_t *info) ieee802154_tx_info_t *info)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
ieee802154_trx_state_t next_state = submac->state == IEEE802154_STATE_LISTEN ieee802154_trx_state_t next_state = submac->state == IEEE802154_STATE_LISTEN
? IEEE802154_TRX_STATE_RX_ON ? IEEE802154_TRX_STATE_RX_ON
@ -69,7 +69,7 @@ static inline bool _does_handle_ack(ieee802154_dev_t *dev)
static int _perform_csma_ca(ieee802154_submac_t *submac) static int _perform_csma_ca(ieee802154_submac_t *submac)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
if (submac->csma_retries_nb <= submac->csma_retries) { if (submac->csma_retries_nb <= submac->csma_retries) {
_req_set_trx_state_wait_busy(dev, IEEE802154_TRX_STATE_TX_ON); _req_set_trx_state_wait_busy(dev, IEEE802154_TRX_STATE_TX_ON);
@ -117,7 +117,7 @@ static int _perform_csma_ca(ieee802154_submac_t *submac)
*/ */
int ieee802154_csma_ca_transmit(ieee802154_submac_t *submac) int ieee802154_csma_ca_transmit(ieee802154_submac_t *submac)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
/* If radio has Auto CSMA-CA or Frame Retransmissions, simply send and wait for the transmit confirmation. */ /* If radio has Auto CSMA-CA or Frame Retransmissions, simply send and wait for the transmit confirmation. */
if (ieee802154_radio_has_auto_csma(dev) || if (ieee802154_radio_has_auto_csma(dev) ||
@ -147,7 +147,7 @@ static bool _has_retrans_left(ieee802154_submac_t *submac)
static void _perform_retrans(ieee802154_submac_t *submac) static void _perform_retrans(ieee802154_submac_t *submac)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
if (_has_retrans_left(submac)) { if (_has_retrans_left(submac)) {
submac->retrans++; submac->retrans++;
@ -171,8 +171,8 @@ void ieee802154_submac_ack_timeout_fired(ieee802154_submac_t *submac)
void ieee802154_submac_crc_error_cb(ieee802154_submac_t *submac) void ieee802154_submac_crc_error_cb(ieee802154_submac_t *submac)
{ {
ieee802154_dev_t *dev = submac->dev;
ieee802154_dev_t *dev = &submac->dev;
/* switch back to RX_ON state */ /* switch back to RX_ON state */
_req_set_trx_state_wait_busy(dev, IEEE802154_TRX_STATE_RX_ON); _req_set_trx_state_wait_busy(dev, IEEE802154_TRX_STATE_RX_ON);
while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {} while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {}
@ -181,7 +181,7 @@ void ieee802154_submac_crc_error_cb(ieee802154_submac_t *submac)
/* All callbacks run in the same context */ /* All callbacks run in the same context */
void ieee802154_submac_rx_done_cb(ieee802154_submac_t *submac) void ieee802154_submac_rx_done_cb(ieee802154_submac_t *submac)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
if (!_does_handle_ack(dev) && submac->wait_for_ack) { if (!_does_handle_ack(dev) && submac->wait_for_ack) {
uint8_t ack[3]; uint8_t ack[3];
@ -192,12 +192,13 @@ void ieee802154_submac_rx_done_cb(ieee802154_submac_t *submac)
ieee802154_tx_info_t tx_info; ieee802154_tx_info_t tx_info;
tx_info.retrans = submac->retrans; tx_info.retrans = submac->retrans;
bool fp = (ack[0] & IEEE802154_FCF_FRAME_PEND); bool fp = (ack[0] & IEEE802154_FCF_FRAME_PEND);
ieee802154_radio_set_frame_filter_mode(submac->dev, IEEE802154_FILTER_ACCEPT); ieee802154_radio_set_frame_filter_mode(&submac->dev, IEEE802154_FILTER_ACCEPT);
_tx_end(submac, fp ? TX_STATUS_FRAME_PENDING : TX_STATUS_SUCCESS, _tx_end(submac, fp ? TX_STATUS_FRAME_PENDING : TX_STATUS_SUCCESS,
&tx_info); &tx_info);
} }
} }
else { else {
assert(!submac->tx);
submac->cb->rx_done(submac); submac->cb->rx_done(submac);
/* Only set the radio to the SubMAC default state only if the upper /* Only set the radio to the SubMAC default state only if the upper
@ -213,15 +214,15 @@ void ieee802154_submac_rx_done_cb(ieee802154_submac_t *submac)
* transition here in order to release it */ * transition here in order to release it */
ieee802154_trx_state_t next_state = submac->state == IEEE802154_STATE_LISTEN ? IEEE802154_TRX_STATE_RX_ON : IEEE802154_TRX_STATE_TRX_OFF; ieee802154_trx_state_t next_state = submac->state == IEEE802154_STATE_LISTEN ? IEEE802154_TRX_STATE_RX_ON : IEEE802154_TRX_STATE_TRX_OFF;
_req_set_trx_state_wait_busy(submac->dev, next_state); _req_set_trx_state_wait_busy(&submac->dev, next_state);
while (ieee802154_radio_confirm_set_trx_state(submac->dev) == -EAGAIN) {} while (ieee802154_radio_confirm_set_trx_state(&submac->dev) == -EAGAIN) {}
} }
} }
static void _handle_tx_success(ieee802154_submac_t *submac, static void _handle_tx_success(ieee802154_submac_t *submac,
ieee802154_tx_info_t *info) ieee802154_tx_info_t *info)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
ieee802154_radio_request_set_trx_state(dev, IEEE802154_TRX_STATE_RX_ON); ieee802154_radio_request_set_trx_state(dev, IEEE802154_TRX_STATE_RX_ON);
while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {} while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {}
@ -243,7 +244,7 @@ static void _handle_tx_success(ieee802154_submac_t *submac,
static void _handle_tx_medium_busy(ieee802154_submac_t *submac) static void _handle_tx_medium_busy(ieee802154_submac_t *submac)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
if (ieee802154_radio_has_frame_retrans(dev) || if (ieee802154_radio_has_frame_retrans(dev) ||
ieee802154_radio_has_auto_csma(dev)) { ieee802154_radio_has_auto_csma(dev)) {
@ -257,7 +258,7 @@ static void _handle_tx_medium_busy(ieee802154_submac_t *submac)
static void _handle_tx_no_ack(ieee802154_submac_t *submac) static void _handle_tx_no_ack(ieee802154_submac_t *submac)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
if (ieee802154_radio_has_frame_retrans(dev)) { if (ieee802154_radio_has_frame_retrans(dev)) {
_tx_end(submac, TX_STATUS_NO_ACK, NULL); _tx_end(submac, TX_STATUS_NO_ACK, NULL);
@ -270,7 +271,7 @@ static void _handle_tx_no_ack(ieee802154_submac_t *submac)
void ieee802154_submac_tx_done_cb(ieee802154_submac_t *submac) void ieee802154_submac_tx_done_cb(ieee802154_submac_t *submac)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
ieee802154_tx_info_t info; ieee802154_tx_info_t info;
ieee802154_radio_confirm_transmit(dev, &info); ieee802154_radio_confirm_transmit(dev, &info);
@ -294,7 +295,7 @@ void ieee802154_submac_tx_done_cb(ieee802154_submac_t *submac)
int ieee802154_send(ieee802154_submac_t *submac, const iolist_t *iolist) int ieee802154_send(ieee802154_submac_t *submac, const iolist_t *iolist)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
uint8_t *buf = iolist->iol_base; uint8_t *buf = iolist->iol_base;
bool cnf = buf[0] & IEEE802154_FCF_ACK_REQ; bool cnf = buf[0] & IEEE802154_FCF_ACK_REQ;
@ -323,7 +324,7 @@ int ieee802154_send(ieee802154_submac_t *submac, const iolist_t *iolist)
int ieee802154_submac_init(ieee802154_submac_t *submac, const network_uint16_t *short_addr, int ieee802154_submac_init(ieee802154_submac_t *submac, const network_uint16_t *short_addr,
const eui64_t *ext_addr) const eui64_t *ext_addr)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
submac->tx = false; submac->tx = false;
submac->state = IEEE802154_STATE_LISTEN; submac->state = IEEE802154_STATE_LISTEN;
@ -407,7 +408,7 @@ int ieee802154_submac_init(ieee802154_submac_t *submac, const network_uint16_t *
int ieee802154_set_phy_conf(ieee802154_submac_t *submac, uint16_t channel_num, int ieee802154_set_phy_conf(ieee802154_submac_t *submac, uint16_t channel_num,
uint8_t channel_page, int8_t tx_pow) uint8_t channel_page, int8_t tx_pow)
{ {
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
const ieee802154_phy_conf_t conf = const ieee802154_phy_conf_t conf =
{ .phy_mode = submac->phy_mode, { .phy_mode = submac->phy_mode,
.channel = channel_num, .channel = channel_num,
@ -442,7 +443,7 @@ int ieee802154_set_state(ieee802154_submac_t *submac, ieee802154_submac_state_t
{ {
int res; int res;
ieee802154_dev_t *dev = submac->dev; ieee802154_dev_t *dev = &submac->dev;
if (submac->tx) { if (submac->tx) {
return -EBUSY; return -EBUSY;

View File

@ -20,6 +20,13 @@
#include "net/ieee802154/radio.h" #include "net/ieee802154/radio.h"
#define RADIOS_NUMOF IS_USED(MODULE_CC2538_RF) + \
IS_USED(MODULE_NRF802154)
#if RADIOS_NUMOF == 0
#error "Radio is not supported"
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -29,8 +36,15 @@ extern "C" {
* @internal * @internal
* @{ * @{
*/ */
void ieee802154_hal_test_init_devs(void); typedef enum {
ieee802154_dev_t *ieee802154_hal_test_get_dev(int id); IEEE802154_DEV_TYPE_CC2538_RF,
IEEE802154_DEV_TYPE_NRF802154,
} ieee802154_dev_type_t;
typedef ieee802154_dev_t* (*ieee802154_dev_cb_t)(ieee802154_dev_type_t type,
void *opaque);
void ieee802154_hal_test_init_devs(ieee802154_dev_cb_t cb, void *opaque);
/** /**
* @} * @}
*/ */

View File

@ -21,6 +21,7 @@
#include "assert.h" #include "assert.h"
#include "kernel_defines.h" #include "kernel_defines.h"
#include "net/ieee802154/radio.h" #include "net/ieee802154/radio.h"
#include "common.h"
#ifdef MODULE_CC2538_RF #ifdef MODULE_CC2538_RF
#include "cc2538_rf.h" #include "cc2538_rf.h"
@ -30,56 +31,23 @@
#include "nrf802154.h" #include "nrf802154.h"
#endif #endif
#ifdef MODULE_CC2538_RF void ieee802154_hal_test_init_devs(ieee802154_dev_cb_t cb, void *opaque)
extern ieee802154_dev_t cc2538_rf_dev;
#endif
#ifdef MODULE_NRF802154
extern ieee802154_dev_t nrf802154_hal_dev;
#endif
#define RADIOS_NUMOF IS_USED(MODULE_CC2538_RF) + \
IS_USED(MODULE_NRF802154)
#if RADIOS_NUMOF == 0
#error "Radio is not supported"
#endif
static ieee802154_dev_t *_radios[RADIOS_NUMOF];
static void _register_radios(void)
{ {
int i=0;
#ifdef MODULE_CC2538_RF
_radios[i++] = &cc2538_rf_dev;
#endif
#ifdef MODULE_NRF802154
_radios[i++] = &nrf802154_hal_dev;
#endif
assert(i == RADIOS_NUMOF);
}
void ieee802154_hal_test_init_devs(void)
{
/* Register all radios */
_register_radios();
/* Call the init function of the device (this should be handled by /* Call the init function of the device (this should be handled by
* `auto_init`) */ * `auto_init`) */
ieee802154_dev_t *radio = NULL;
(void) radio;
#ifdef MODULE_CC2538_RF #ifdef MODULE_CC2538_RF
if ((radio = cb(IEEE802154_DEV_TYPE_CC2538_RF, opaque)) ){
cc2538_rf_hal_setup(radio);
cc2538_init(); cc2538_init();
}
#endif #endif
#ifdef MODULE_NRF802154 #ifdef MODULE_NRF802154
if ((radio = cb(IEEE802154_DEV_TYPE_NRF802154, opaque)) ){
nrf802154_hal_setup(radio);
nrf802154_init(); nrf802154_init();
}
#endif #endif
} }
ieee802154_dev_t *ieee802154_hal_test_get_dev(int id)
{
assert(id < RADIOS_NUMOF);
return _radios[id];
}

View File

@ -36,11 +36,8 @@
#include "xtimer.h" #include "xtimer.h"
#define SYMBOL_TIME (16U) /**< 16 us */ #define SYMBOL_TIME (16U) /**< 16 us */
#define ACK_TIMEOUT_TIME (40 * SYMBOL_TIME) #define ACK_TIMEOUT_TIME (40 * SYMBOL_TIME)
#define RADIO_DEFAULT_ID (0U)
static inline void _set_trx_state(int state, bool verbose); static inline void _set_trx_state(int state, bool verbose);
static uint8_t buffer[127]; static uint8_t buffer[127];
@ -52,6 +49,8 @@ static eui64_t ext_addr;
static network_uint16_t short_addr; static network_uint16_t short_addr;
static uint8_t seq; static uint8_t seq;
static ieee802154_dev_t _radio[RADIOS_NUMOF];
static void _print_packet(size_t size, uint8_t lqi, int16_t rssi) static void _print_packet(size_t size, uint8_t lqi, int16_t rssi)
{ {
if (buffer[0] & IEEE802154_FCF_TYPE_ACK && ((seq-1) == buffer[2])) { if (buffer[0] & IEEE802154_FCF_TYPE_ACK && ((seq-1) == buffer[2])) {
@ -83,7 +82,7 @@ static int print_addr(int argc, char **argv)
static void _ack_timeout(event_t *event) static void _ack_timeout(event_t *event)
{ {
(void) event; (void) event;
ieee802154_dev_t *dev = ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID); ieee802154_dev_t *dev = &_radio[0];
ieee802154_radio_set_frame_filter_mode(dev, IEEE802154_FILTER_ACCEPT); ieee802154_radio_set_frame_filter_mode(dev, IEEE802154_FILTER_ACCEPT);
} }
@ -106,7 +105,7 @@ void _crc_error_handler(event_t *event)
{ {
(void) event; (void) event;
puts("Packet with invalid CRC received"); puts("Packet with invalid CRC received");
ieee802154_dev_t* dev = ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID); ieee802154_dev_t* dev = &_radio[0];
/* switch back to RX_ON state */ /* switch back to RX_ON state */
ieee802154_radio_request_set_trx_state(dev, IEEE802154_TRX_STATE_RX_ON); ieee802154_radio_request_set_trx_state(dev, IEEE802154_TRX_STATE_RX_ON);
while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {} while (ieee802154_radio_confirm_set_trx_state(dev) == -EAGAIN) {}
@ -126,7 +125,7 @@ void _rx_done_handler(event_t *event)
* NOTE: It's possible to call `ieee802154_radio_len` to retrieve the packet * NOTE: It's possible to call `ieee802154_radio_len` to retrieve the packet
* length. Since the buffer is fixed in this test, we don't use it * length. Since the buffer is fixed in this test, we don't use it
*/ */
int size = ieee802154_radio_read(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), buffer, 127, &info); int size = ieee802154_radio_read(&_radio[0], buffer, 127, &info);
if (size > 0) { if (size > 0) {
/* Print packet while we wait for the state transition */ /* Print packet while we wait for the state transition */
_print_packet(size, info.lqi, info.rssi); _print_packet(size, info.lqi, info.rssi);
@ -167,9 +166,9 @@ static void _tx_finish_handler(event_t *event)
(void) event; (void) event;
/* The TX_DONE event indicates it's safe to call the confirm counterpart */ /* The TX_DONE event indicates it's safe to call the confirm counterpart */
assert(ieee802154_radio_confirm_transmit(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), &tx_info) >= 0); assert(ieee802154_radio_confirm_transmit(&_radio[0], &tx_info) >= 0);
if (!ieee802154_radio_has_irq_ack_timeout(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID)) && !ieee802154_radio_has_frame_retrans(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (!ieee802154_radio_has_irq_ack_timeout(&_radio[0]) && !ieee802154_radio_has_frame_retrans(&_radio[0])) {
/* This is just to show how the MAC layer would handle ACKs... */ /* This is just to show how the MAC layer would handle ACKs... */
_set_trx_state(IEEE802154_TRX_STATE_RX_ON, false); _set_trx_state(IEEE802154_TRX_STATE_RX_ON, false);
xtimer_set(&timer_ack, ACK_TIMEOUT_TIME); xtimer_set(&timer_ack, ACK_TIMEOUT_TIME);
@ -192,7 +191,7 @@ static void _tx_finish_handler(event_t *event)
puts(""); puts("");
if (ieee802154_radio_has_frame_retrans_info(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_frame_retrans_info(&_radio[0])) {
printf("Retransmission attempts: %i\n", tx_info.retrans); printf("Retransmission attempts: %i\n", tx_info.retrans);
} }
@ -206,28 +205,57 @@ static event_t _tx_finish_ev = {
static void _send(iolist_t *pkt) static void _send(iolist_t *pkt)
{ {
/* Request a state change to RX_ON */ /* Request a state change to RX_ON */
ieee802154_radio_request_set_trx_state(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), IEEE802154_TRX_STATE_TX_ON); ieee802154_radio_request_set_trx_state(&_radio[0], IEEE802154_TRX_STATE_TX_ON);
/* Write the packet to the radio */ /* Write the packet to the radio */
ieee802154_radio_write(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), pkt); ieee802154_radio_write(&_radio[0], pkt);
/* Block until the radio confirms the state change */ /* Block until the radio confirms the state change */
while(ieee802154_radio_confirm_set_trx_state(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID)) == -EAGAIN); while(ieee802154_radio_confirm_set_trx_state(&_radio[0]) == -EAGAIN);
/* Trigger the transmit and wait for the mutex unlock (TX_DONE event) */ /* Trigger the transmit and wait for the mutex unlock (TX_DONE event) */
ieee802154_radio_set_frame_filter_mode(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), IEEE802154_FILTER_ACK_ONLY); ieee802154_radio_set_frame_filter_mode(&_radio[0], IEEE802154_FILTER_ACK_ONLY);
ieee802154_radio_request_transmit(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID)); ieee802154_radio_request_transmit(&_radio[0]);
mutex_lock(&lock); mutex_lock(&lock);
event_post(EVENT_PRIO_HIGHEST, &_tx_finish_ev); event_post(EVENT_PRIO_HIGHEST, &_tx_finish_ev);
} }
struct _reg_container {
int count;
};
static ieee802154_dev_t *_reg_callback(ieee802154_dev_type_t type, void *opaque)
{
struct _reg_container *reg = opaque;
printf("Trying to register ");
switch(type) {
case IEEE802154_DEV_TYPE_CC2538_RF:
printf("cc2538_rf");
break;
case IEEE802154_DEV_TYPE_NRF802154:
printf("nrf52840");
break;
}
puts(".");
if (reg->count > 0) {
puts("For the moment this test only supports one radio");
return NULL;
}
puts("Success");
return &_radio[reg->count++];
}
static int _init(void) static int _init(void)
{ {
ieee802154_hal_test_init_devs(); struct _reg_container reg = {0};
ieee802154_hal_test_init_devs(_reg_callback, &reg);
/* Set the Event Notification */ /* Set the Event Notification */
((ieee802154_dev_t*) ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))->cb = _hal_radio_cb; ((ieee802154_dev_t*) &_radio[0])->cb = _hal_radio_cb;
/* Note that addresses are not kept in the radio. This assumes MAC layers /* Note that addresses are not kept in the radio. This assumes MAC layers
* already have a copy of the address */ * already have a copy of the address */
@ -236,28 +264,28 @@ static int _init(void)
/* Since the device was already initialized, turn on the radio. /* Since the device was already initialized, turn on the radio.
* The transceiver state will be "TRX_OFF" */ * The transceiver state will be "TRX_OFF" */
ieee802154_radio_request_on(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID)); ieee802154_radio_request_on(&_radio[0]);
while(ieee802154_radio_confirm_on(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID)) == -EAGAIN) {} while(ieee802154_radio_confirm_on(&_radio[0]) == -EAGAIN) {}
ieee802154_radio_set_frame_filter_mode(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), IEEE802154_FILTER_ACCEPT); ieee802154_radio_set_frame_filter_mode(&_radio[0], IEEE802154_FILTER_ACCEPT);
uint16_t panid = CONFIG_IEEE802154_DEFAULT_PANID; uint16_t panid = CONFIG_IEEE802154_DEFAULT_PANID;
/* Set all IEEE addresses */ /* Set all IEEE addresses */
ieee802154_radio_config_addr_filter(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), ieee802154_radio_config_addr_filter(&_radio[0],
IEEE802154_AF_SHORT_ADDR, &short_addr); IEEE802154_AF_SHORT_ADDR, &short_addr);
ieee802154_radio_config_addr_filter(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), ieee802154_radio_config_addr_filter(&_radio[0],
IEEE802154_AF_EXT_ADDR, &ext_addr); IEEE802154_AF_EXT_ADDR, &ext_addr);
ieee802154_radio_config_addr_filter(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), ieee802154_radio_config_addr_filter(&_radio[0],
IEEE802154_AF_PANID, &panid); IEEE802154_AF_PANID, &panid);
/* Set PHY configuration */ /* Set PHY configuration */
ieee802154_phy_conf_t conf = {.channel=CONFIG_IEEE802154_DEFAULT_CHANNEL, .page=CONFIG_IEEE802154_DEFAULT_SUBGHZ_PAGE, .pow=CONFIG_IEEE802154_DEFAULT_TXPOWER}; ieee802154_phy_conf_t conf = {.channel=CONFIG_IEEE802154_DEFAULT_CHANNEL, .page=CONFIG_IEEE802154_DEFAULT_SUBGHZ_PAGE, .pow=CONFIG_IEEE802154_DEFAULT_TXPOWER};
ieee802154_radio_config_phy(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), &conf); ieee802154_radio_config_phy(&_radio[0], &conf);
/* ieee802154_radio_set_cca_mode*/ /* ieee802154_radio_set_cca_mode*/
ieee802154_radio_set_cca_mode(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), IEEE802154_CCA_MODE_ED_THRESHOLD); ieee802154_radio_set_cca_mode(&_radio[0], IEEE802154_CCA_MODE_ED_THRESHOLD);
ieee802154_radio_set_cca_threshold(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), CONFIG_IEEE802154_CCA_THRESH_DEFAULT); ieee802154_radio_set_cca_threshold(&_radio[0], CONFIG_IEEE802154_CCA_THRESH_DEFAULT);
/* Set the transceiver state to RX_ON in order to receive packets */ /* Set the transceiver state to RX_ON in order to receive packets */
_set_trx_state(IEEE802154_TRX_STATE_RX_ON, false); _set_trx_state(IEEE802154_TRX_STATE_RX_ON, false);
@ -377,9 +405,9 @@ int _cca(int argc, char **argv)
{ {
(void) argc; (void) argc;
(void) argv; (void) argv;
ieee802154_radio_request_cca(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID)); ieee802154_radio_request_cca(&_radio[0]);
mutex_lock(&lock); mutex_lock(&lock);
int res = ieee802154_radio_confirm_cca(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID)); int res = ieee802154_radio_confirm_cca(&_radio[0]);
assert(res >= 0); assert(res >= 0);
if (res > 0) { if (res > 0) {
@ -395,7 +423,7 @@ int _cca(int argc, char **argv)
static inline void _set_trx_state(int state, bool verbose) static inline void _set_trx_state(int state, bool verbose)
{ {
xtimer_ticks32_t a; xtimer_ticks32_t a;
int res = ieee802154_radio_request_set_trx_state(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), state); int res = ieee802154_radio_request_set_trx_state(&_radio[0], state);
if (verbose) { if (verbose) {
a = xtimer_now(); a = xtimer_now();
if(res != 0) { if(res != 0) {
@ -404,7 +432,7 @@ static inline void _set_trx_state(int state, bool verbose)
} }
} }
while ((res = ieee802154_radio_confirm_set_trx_state(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) == -EAGAIN) {} while ((res = ieee802154_radio_confirm_set_trx_state(&_radio[0])) == -EAGAIN) {}
if (verbose) { if (verbose) {
if (res != 0) { if (res != 0) {
printf("%i != 0 \n", res); printf("%i != 0 \n", res);
@ -476,7 +504,7 @@ static int promisc(int argc, char **argv)
puts("Disabled promiscuos mode"); puts("Disabled promiscuos mode");
} }
ieee802154_radio_set_frame_filter_mode(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID), conf); ieee802154_radio_set_frame_filter_mode(&_radio[0], conf);
return 0; return 0;
} }
@ -525,7 +553,7 @@ int config_phy(int argc, char **argv)
return 1; return 1;
} }
_set_trx_state(IEEE802154_TRX_STATE_TRX_OFF, false); _set_trx_state(IEEE802154_TRX_STATE_TRX_OFF, false);
ieee802154_dev_t *dev = ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID); ieee802154_dev_t *dev = &_radio[0];
ieee802154_phy_conf_t conf = {.phy_mode=phy_mode, .channel=channel, .page=0, .pow=tx_pow}; ieee802154_phy_conf_t conf = {.phy_mode=phy_mode, .channel=channel, .page=0, .pow=tx_pow};
if (ieee802154_radio_config_phy(dev, &conf) < 0) { if (ieee802154_radio_config_phy(dev, &conf) < 0) {
puts("Channel or TX power settings not supported"); puts("Channel or TX power settings not supported");
@ -541,7 +569,7 @@ int config_phy(int argc, char **argv)
int txmode_cmd(int argc, char **argv) int txmode_cmd(int argc, char **argv)
{ {
ieee802154_dev_t *dev = ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID); ieee802154_dev_t *dev = &_radio[0];
if (argc < 2) { if (argc < 2) {
printf("Usage: %s <csma_ca|cca|direct>\n", argv[0]); printf("Usage: %s <csma_ca|cca|direct>\n", argv[0]);
@ -572,7 +600,7 @@ int txmode_cmd(int argc, char **argv)
static int _config_cca_cmd(int argc, char **argv) static int _config_cca_cmd(int argc, char **argv)
{ {
ieee802154_dev_t *dev = ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID); ieee802154_dev_t *dev = &_radio[0];
ieee802154_cca_mode_t mode; ieee802154_cca_mode_t mode;
if (argc < 2) { if (argc < 2) {
@ -633,63 +661,63 @@ static int _caps_cmd(int argc, char **argv)
bool has_phy_mr_ofdm = false; bool has_phy_mr_ofdm = false;
bool has_phy_mr_fsk = false; bool has_phy_mr_fsk = false;
if (ieee802154_radio_has_frame_retrans(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_frame_retrans(&_radio[0])) {
has_frame_retrans = true; has_frame_retrans = true;
} }
if (ieee802154_radio_has_auto_csma(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_auto_csma(&_radio[0])) {
has_auto_csma = true; has_auto_csma = true;
} }
if (ieee802154_radio_has_24_ghz(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_24_ghz(&_radio[0])) {
has_24_ghz = true; has_24_ghz = true;
} }
if (ieee802154_radio_has_sub_ghz(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_sub_ghz(&_radio[0])) {
has_sub_ghz = true; has_sub_ghz = true;
} }
if (ieee802154_radio_has_irq_tx_done(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_irq_tx_done(&_radio[0])) {
has_irq_tx_done = true; has_irq_tx_done = true;
} }
if (ieee802154_radio_has_irq_rx_start(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_irq_rx_start(&_radio[0])) {
has_irq_rx_start = true; has_irq_rx_start = true;
} }
if (ieee802154_radio_has_irq_ack_timeout(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_irq_ack_timeout(&_radio[0])) {
has_irq_ack_timeout = true; has_irq_ack_timeout = true;
} }
if (ieee802154_radio_has_irq_cca_done(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_irq_cca_done(&_radio[0])) {
has_irq_cca_done = true; has_irq_cca_done = true;
} }
if (ieee802154_radio_has_frame_retrans_info(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_frame_retrans_info(&_radio[0])) {
has_frame_retrans_info = true; has_frame_retrans_info = true;
} }
if (ieee802154_radio_has_phy_bpsk(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_phy_bpsk(&_radio[0])) {
has_phy_bpsk = true; has_phy_bpsk = true;
} }
if (ieee802154_radio_has_phy_ask(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_phy_ask(&_radio[0])) {
has_phy_ask = true; has_phy_ask = true;
} }
if (ieee802154_radio_has_phy_oqpsk(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_phy_oqpsk(&_radio[0])) {
has_phy_oqpsk = true; has_phy_oqpsk = true;
} }
if (ieee802154_radio_has_phy_mr_oqpsk(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_phy_mr_oqpsk(&_radio[0])) {
has_phy_mr_oqpsk = true; has_phy_mr_oqpsk = true;
} }
if (ieee802154_radio_has_phy_mr_ofdm(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_phy_mr_ofdm(&_radio[0])) {
has_phy_mr_ofdm = true; has_phy_mr_ofdm = true;
} }
if (ieee802154_radio_has_phy_mr_fsk(ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID))) { if (ieee802154_radio_has_phy_mr_fsk(&_radio[0])) {
has_phy_mr_fsk = true; has_phy_mr_fsk = true;
} }

View File

@ -203,15 +203,43 @@ static void _event_cb(netdev_t *dev, netdev_event_t event)
} }
} }
} }
struct _reg_container {
int count;
};
static ieee802154_dev_t *_reg_callback(ieee802154_dev_type_t type, void *opaque)
{
struct _reg_container *reg = opaque;
printf("Trying to register ");
switch(type) {
case IEEE802154_DEV_TYPE_CC2538_RF:
printf("cc2538_rf");
break;
case IEEE802154_DEV_TYPE_NRF802154:
printf("nrf52840");
break;
}
puts(".");
if (reg->count > 0) {
puts("For the moment this test only supports one radio");
return NULL;
}
puts("Success");
return &netdev_submac.submac.dev;
}
static int _init(void) static int _init(void)
{ {
ieee802154_hal_test_init_devs();
netdev_t *dev = &netdev_submac.dev.netdev; netdev_t *dev = &netdev_submac.dev.netdev;
dev->event_callback = _event_cb; dev->event_callback = _event_cb;
netdev_ieee802154_submac_init(&netdev_submac, struct _reg_container reg = {0};
ieee802154_hal_test_get_dev(RADIO_DEFAULT_ID)); netdev_ieee802154_submac_init(&netdev_submac);
ieee802154_hal_test_init_devs(_reg_callback, &reg);
dev->driver->init(dev); dev->driver->init(dev);
return 0; return 0;
} }