Merge pull request #15145 from fjmolinas/pr_openwsn_radio_hal

pkg/openwsn: add ieee802154_hal based radio
This commit is contained in:
José Alamos 2020-10-23 21:26:21 +02:00 committed by GitHub
commit e8721ce415
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 581 additions and 51 deletions

View File

@ -13,6 +13,7 @@ config BOARD_CC2538DK
select CPU_MODEL_CC2538NF53
select HAS_PERIPH_ADC
select HAS_PERIPH_I2C
select HAS_PERIPH_RTT
select HAS_PERIPH_SPI
select HAS_PERIPH_TIMER
select HAS_PERIPH_UART

View File

@ -4,6 +4,7 @@ CPU_MODEL ?= cc2538nf53
# Put defined MCU peripherals here (in alphabetical order)
FEATURES_PROVIDED += periph_adc
FEATURES_PROVIDED += periph_i2c
FEATURES_PROVIDED += periph_rtt
FEATURES_PROVIDED += periph_spi
FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += periph_uart

View File

@ -1,3 +1,8 @@
# ATM openwsn does not support the at86rf215 radio
ifneq (,$(filter openwsn,$(USEPKG)))
USEMODULE += cc2538_rf
endif
ifneq (,$(filter netdev_default,$(USEMODULE)))
ifeq (,$(filter cc2538_rf,$(USEMODULE)))
USEMODULE += at86rf215

View File

@ -86,6 +86,30 @@
#define CONFIG_CC2538_RF_OBS_SIG_2_PCX 7 /* PC7 */
/** @} */
/**
* @name OpenWSN leds configuration
* @{
*/
#define OPENWSN_LEDPIN_ERROR LED0_PIN
#define OPENWSN_LEDPIN_SYNC LED1_PIN
#define OPENWSN_LEDPIN_RADIO LED3_PIN
#define OPENWSN_LEDPIN_DEBUG LED2_PIN
/** @} */
/**
* @name OpenWSN debugpins configuration
*
* @note This configuration mimics the one done in OpenWSN-fw for the
* same platform
* @{
*/
#define OPENWSN_DEBUGPIN_FRAME GPIO_PIN(0, 7) /* A7 */
#define OPENWSN_DEBUGPIN_ISR GPIO_PIN(2, 3) /* C3 */
#define OPENWSN_DEBUGPIN_SLOT GPIO_PIN(1, 3) /* B3 */
#define OPENWSN_DEBUGPIN_FSM GPIO_PIN(1, 2) /* B2 */
#define OPENWSN_DEBUGPIN_TASK GPIO_PIN(1, 1) /* B1 */
#define OPENWSN_DEBUGPIN_RADIO GPIO_PIN(1, 0) /* B0 */
/**
* @name AT86RF215 configuration
* @{

View File

@ -266,7 +266,7 @@ enum {
#define CONFIG_CC2538_RF_OBS_2 rssi_valid
#endif
/* Default configration for cc2538dk or similar */
/* Default configuration for cc2538dk or similar */
#ifndef CONFIG_CC2538_RF_OBS_SIG_0_PCX
#define CONFIG_CC2538_RF_OBS_SIG_0_PCX 0 /* PC0 = LED_1 (red) */
#endif

View File

@ -43,6 +43,19 @@ extern "C" {
#define CPU_HAS_BITBAND (1)
/** @} */
/**
* @name OpenWSN timing constants
*
* @{
*/
/* Taken from openwsn-fw */
#define PORT_maxTxDataPrepare (460/PORT_US_PER_TICK)
#define PORT_maxRxAckPrepare (300/PORT_US_PER_TICK)
#define PORT_maxRxDataPrepare (300/PORT_US_PER_TICK)
#define PORT_maxTxAckPrepare (460/PORT_US_PER_TICK)
#define PORT_delayTx (400/PORT_US_PER_TICK)
/** @} */
#ifdef __cplusplus
} /* end extern "C" */
#endif

View File

@ -125,6 +125,23 @@ extern "C" {
#endif /* SOFTDEVICE_PRESENT */
/** @} */
#ifdef CPU_MODEL_NRF52840XXAA
/**
* @name OpenWSN timing constants
*
* @{
*/
/* Taken from OpenWSN @32.768Hz */
#define PORT_maxTxDataPrepare (400/PORT_US_PER_TICK)
#define PORT_maxRxAckPrepare (400/PORT_US_PER_TICK)
#define PORT_maxRxDataPrepare (400/PORT_US_PER_TICK)
#define PORT_maxTxAckPrepare (400/PORT_US_PER_TICK)
/* Measured 220us */
#define PORT_delayTx (300/PORT_US_PER_TICK)
#define PORT_delayRx (150/PORT_US_PER_TICK)
/** @} */
#endif
/**
* @brief Put the CPU in the low-power 'wait for event' state
*/

View File

@ -16,8 +16,6 @@ ifneq (,$(filter openwsn_openstack,$(USEMODULE)))
DEFAULT_MODULE += auto_init_openwsn
USEMODULE += luid
USEMODULE += netdev_default
endif
ifneq (,$(filter openwsn_scheduler,$(USEMODULE)))
@ -50,6 +48,23 @@ ifneq (,$(filter openwsn_crypto,$(USEMODULE)))
USEMODULE += cipher_modes
endif
ifneq (,$(filter openwsn_radio,$(USEMODULE)))
USEMODULE += netdev_default
USEMODULE += luid
ifneq (,$(filter cc2538_rf nrf802154,$(USEMODULE)))
USEMODULE += openwsn_radio_hal
endif
ifneq (,$(filter at86rf2xx,$(USEMODULE)))
USEMODULE += openwsn_radio_netdev
endif
endif
ifneq (,$(filter openwsn_radio_hal,$(USEMODULE)))
USEMODULE += ieee802154_radio_hal
# Used here only for dependency resolution
DISABLE_MODULE += auto_init_gnrc_netif
endif
ifneq (,$(filter openwsn_sctimer,$(USEMODULE)))
ifeq (,$(filter openwsn_sctimer_ztimer,$(USEMODULE)))
USEMODULE += openwsn_sctimer_rtt

View File

@ -84,5 +84,13 @@ ifneq (,$(filter at86rf2xx,$(USEMODULE)))
CFLAGS += -DAT86RF2XX_BASIC_MODE
endif
# We want the highest possible frequency set for periph_rtt, but not all
# platforms can configure this value. use highest possible RTT_FREQUENCY
# for platforms that allow it
ifneq (,$(filter stm32 nrf52 sam%,$(CPU)))
RTT_FREQUENCY ?= RTT_MAX_FREQUENCY
CFLAGS += -DRTT_FREQUENCY=$(RTT_FREQUENCY)
endif
# LLVM ARM shows issues with missing definitions for stdatomic
TOOLCHAINS_BLACKLIST += llvm

View File

@ -1,6 +1,6 @@
MODULE = openwsn
SRC := $(filter-out sctimer_% ,$(wildcard *.c))
SRC := $(filter-out sctimer_% radio_%,$(wildcard *.c))
ifneq (,$(filter openwsn_sctimer_rtt,$(USEMODULE)))
SRC += sctimer_rtt.c
@ -10,4 +10,12 @@ ifneq (,$(filter openwsn_sctimer_ztimer,$(USEMODULE)))
SRC += sctimer_ztimer.c
endif
ifneq (,$(filter openwsn_radio_hal,$(USEMODULE)))
SRC += radio_hal.c
endif
ifneq (,$(filter openwsn_radio_netdev,$(USEMODULE)))
SRC += radio_netdev.c
endif
include $(RIOTBASE)/Makefile.base

View File

@ -29,8 +29,21 @@
extern openwsn_radio_t openwsn_radio;
#ifdef MODULE_OPENWSN_RADIO_HAL
/* HACK: temporary hack while eui_provider still depends on netdev */
static eui64_t _eui64;
static bool _eui64_is_set = false;
#endif
void eui64_get(uint8_t *addressToWrite)
{
#ifdef MODULE_OPENWSN_RADIO_HAL
if (!_eui64_is_set) {
luid_get_eui64(&_eui64);
_eui64_is_set = true;
}
memcpy(addressToWrite, _eui64.uint8, sizeof(_eui64.uint8));
#else
eui64_t eui64;
if (openwsn_radio.dev->driver->get(openwsn_radio.dev, NETOPT_ADDRESS_LONG,
@ -41,4 +54,5 @@ void eui64_get(uint8_t *addressToWrite)
else {
luid_get_eui64((eui64_t *) addressToWrite);
}
#endif
}

View File

@ -19,7 +19,6 @@
#include "scheduler.h"
#include "openstack.h"
#include "radio.h"
#include "idmanager.h"
#include "openwsn.h"
#include "openwsn_board.h"
@ -30,6 +29,14 @@
#include "at86rf2xx_params.h"
#endif
#ifdef MODULE_CC2538_RF
#include "cc2538_rf.h"
#endif
#ifdef MODULE_NRF802154
#include "nrf802154.h"
#endif
#define LOG_LEVEL LOG_NONE
#include "log.h"
@ -37,9 +44,11 @@
#define OPENWSN_SCHED_PRIO (THREAD_PRIORITY_MAIN - 4)
#define OPENWSN_SCHED_STACKSIZE (2048)
#ifdef MODULE_OPENWSN_RADIO_NETDEV
#ifdef MODULE_AT86RF2XX
static at86rf2xx_t at86rf2xx_dev;
#endif
#endif
static char _stack[OPENWSN_SCHED_STACKSIZE];
@ -52,46 +61,42 @@ kernel_pid_t openwsn_get_pid(void)
return _pid;
}
#ifdef MODULE_OPENWSN_RADIO
void openwsn_set_addr_16b(netdev_t* dev)
void* _radio_init_dev(void)
{
uint8_t addr[IEEE802154_SHORT_ADDRESS_LEN];
dev->driver->get(dev, NETOPT_ADDRESS, addr, IEEE802154_SHORT_ADDRESS_LEN);
open_addr_t id;
id.type = ADDR_16B;
memcpy(&id.addr_16b, addr, IEEE802154_SHORT_ADDRESS_LEN);
idmanager_setMyID(&id);
}
void* dev = NULL;
/* avoid cppcheck style (redundantAssignment)*/
(void) dev;
#ifdef MODULE_OPENWSN_RADIO_NETDEV
#ifdef MODULE_AT86RF2XX
dev = &at86rf2xx_dev.netdev.netdev;
at86rf2xx_setup(&at86rf2xx_dev, &at86rf2xx_params[0], 0);
#endif
#else
#ifdef MODULE_CC2538_RF
extern ieee802154_dev_t cc2538_rf_dev;
dev = &cc2538_rf_dev;
cc2538_init();
#endif
#ifdef MODULE_NRF802154
extern ieee802154_dev_t nrf802154_hal_dev;
dev = &nrf802154_hal_dev;
nrf802154_init();
#endif
#endif
return dev;
}
int openwsn_bootstrap(void)
{
LOG_DEBUG("[openwsn]: init RIOT board\n");
board_init_openwsn();
#ifdef MODULE_AT86RF2XX
netdev_t *netdev = (netdev_t *)&at86rf2xx_dev.netdev.netdev;
at86rf2xx_setup(&at86rf2xx_dev, &at86rf2xx_params[0], 0);
(void) netdev;
#endif
#ifdef MODULE_OPENWSN_RADIO
LOG_DEBUG("[openwsn]: init radio\n");
if (openwsn_radio_init(netdev)) {
void* dev = _radio_init_dev();
if (openwsn_radio_init(dev)) {
LOG_ERROR("[openwsn]: failed to init radio\n");
return -1;
}
#endif
/* Initiate Id manager here and not in `openstack_init` function to allow
overriding the short id address before additional stack components are
initiated */
idmanager_init();
#ifdef MODULE_OPENWSN_RADIO
/* override 16b address to avoid short address collision */
openwsn_set_addr_16b(netdev);
#endif
LOG_DEBUG("[openwsn]: network thread\n");
_pid = thread_create(_stack, OPENWSN_SCHED_STACKSIZE, OPENWSN_SCHED_PRIO,

View File

@ -0,0 +1,317 @@
/*
* Copyright (C) 2020 Inria
*
* 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 pkg_openwsn
* @{
*
* @file
* @brief RIOT adaption of the "radio" bsp module
*
* @author Francisco Molina <francois-xavier.molina@inria.fr>
* @}
*/
#include <sys/uio.h>
#include "leds.h"
#include "debugpins.h"
#include "sctimer.h"
#include "idmanager.h"
#include "eui64.h"
#include "byteorder.h"
#include "luid.h"
#include "net/ieee802154.h"
#include "net/ieee802154/radio.h"
#include "openwsn.h"
#include "openwsn_radio.h"
#define LOG_LEVEL LOG_NONE
#include "log.h"
openwsn_radio_t openwsn_radio;
/* stores the event capture time */
static PORT_TIMER_WIDTH _txrx_event_capture_time = 0;
void _idmanager_addr_override(void)
{
/* Initiate Id manager here and not in `openstack_init` function to
allow overriding the short id address before additional stack
components are initiated */
idmanager_init();
/* override 16b address to avoid short address collision */
network_uint16_t short_addr;
luid_get_short(&short_addr);
open_addr_t id;
id.type = ADDR_16B;
memcpy(&id.addr_16b, short_addr.u8, IEEE802154_SHORT_ADDRESS_LEN);
idmanager_setMyID(&id);
/* override PANID */
id.type = ADDR_PANID;
network_uint16_t panid_be = byteorder_htons(OPENWSN_PANID);
memcpy(&id.panid, &panid_be, IEEE802154_SHORT_ADDRESS_LEN);
idmanager_setMyID(&id);
/* recover ADDR_64B */
eui64_t eui64;
eui64_get(eui64.uint8);
/* Set all IEEE addresses */
uint16_t panid = OPENWSN_PANID;
ieee802154_radio_set_hw_addr_filter(openwsn_radio.dev, &short_addr,
&eui64, &panid);
}
static void _hal_radio_cb(ieee802154_dev_t *dev, ieee802154_trx_ev_t status)
{
(void)dev;
debugpins_isr_set();
_txrx_event_capture_time = sctimer_readCounter();
debugpins_isr_clr();
switch (status) {
case IEEE802154_RADIO_CONFIRM_TX_DONE:
ieee802154_radio_confirm_transmit(openwsn_radio.dev, NULL);
ieee802154_radio_request_set_trx_state(openwsn_radio.dev,
IEEE802154_TRX_STATE_TRX_OFF);
while (ieee802154_radio_confirm_set_trx_state(openwsn_radio.dev) == -EAGAIN) {}
openwsn_radio.endFrame_cb(_txrx_event_capture_time);
break;
case IEEE802154_RADIO_INDICATION_RX_DONE:
openwsn_radio.endFrame_cb(_txrx_event_capture_time);
break;
case IEEE802154_RADIO_INDICATION_TX_START:
openwsn_radio.startFrame_cb(_txrx_event_capture_time);
break;
case IEEE802154_RADIO_INDICATION_RX_START:
openwsn_radio.startFrame_cb(_txrx_event_capture_time);
break;
default:
break;
}
}
int openwsn_radio_init(void *radio_dev)
{
assert(radio_dev);
ieee802154_dev_t *dev = (ieee802154_dev_t *)radio_dev;
LOG_DEBUG("[openwsn/radio]: initialize riot-adaptation\n");
openwsn_radio.dev = dev;
/* override short_address and panid*/
_idmanager_addr_override();
if (ieee802154_radio_request_on(dev)) {
LOG_ERROR("[openwsn/radio]: unable to initialize device\n");
return -1;
}
/* Set the Event Notification */
dev->cb = _hal_radio_cb;
/* If the radio is still not in TRX_OFF state, spin */
while (ieee802154_radio_confirm_on(dev) == -EAGAIN) {}
/* Enable basic mode, no AUTOACK. no CSMA */
ieee802154_radio_set_rx_mode(dev, IEEE802154_RX_AACK_DISABLED);
/* MAC layer retransmissions are disabled by _set_csma_params() */
ieee802154_radio_set_csma_params(dev, NULL, -1);
if (IS_USED(MODULE_CC2538_RF)) {
/* If frame filtering is enabled cc2538 will not accept beacons
where the destination-address mode is 0 (no destination address).
per rfc8180 4.5.1 the destination address must be set, which means
the destination-address mode can't be 0 */
ieee802154_radio_set_rx_mode(dev, IEEE802154_RX_PROMISC);
}
/* Configure PHY settings (channel, TX power) */
ieee802154_phy_conf_t conf =
{ .channel = CONFIG_IEEE802154_DEFAULT_CHANNEL,
.page = CONFIG_IEEE802154_DEFAULT_CHANNEL,
.pow = CONFIG_IEEE802154_DEFAULT_TXPOWER };
ieee802154_radio_config_phy(dev, &conf);
return 0;
}
void radio_setStartFrameCb(radio_capture_cbt cb)
{
openwsn_radio.startFrame_cb = cb;
}
void radio_setEndFrameCb(radio_capture_cbt cb)
{
openwsn_radio.endFrame_cb = cb;
}
void radio_reset(void)
{
/* TODO: this is not handled correctly since not all radios implement
this */
ieee802154_radio_off(openwsn_radio.dev);
ieee802154_radio_request_on(openwsn_radio.dev);
/* If the radio is still not in TRX_OFF state, spin */
while (ieee802154_radio_confirm_on(openwsn_radio.dev) == -EAGAIN) {}
}
void radio_setFrequency(uint8_t frequency, radio_freq_t tx_or_rx)
{
(void)tx_or_rx;
ieee802154_phy_conf_t conf =
{ .channel = frequency,
.page = CONFIG_IEEE802154_DEFAULT_CHANNEL,
.pow = CONFIG_IEEE802154_DEFAULT_TXPOWER };
ieee802154_radio_config_phy(openwsn_radio.dev, &conf);
}
void radio_rfOn(void)
{
ieee802154_radio_request_on(openwsn_radio.dev);
/* If the radio is still not in TRX_OFF state, spin */
while (ieee802154_radio_confirm_on(openwsn_radio.dev) == -EAGAIN) {}
/* HACK: cc2538 does not implement on() correctly, remove when it does*/
ieee802154_radio_request_set_trx_state(openwsn_radio.dev,
IEEE802154_TRX_STATE_TRX_OFF);
while (ieee802154_radio_confirm_set_trx_state(openwsn_radio.dev) == -EAGAIN) {}
}
void radio_rfOff(void)
{
/* radio_rfOff is called in the middle of a slot and is not always
followed by an `radio_rfOn`, so don't call `ieee802154_radio_off`
and only send the radio to `TrxOFF` instead */
int ret = ieee802154_radio_request_set_trx_state(openwsn_radio.dev,
IEEE802154_TRX_STATE_TRX_OFF);
if (ret) {
LOG_ERROR("[openwsn/radio]: request_set_trx_state failed %s\n",
__FUNCTION__);
}
else {
debugpins_radio_clr();
leds_radio_off();
while (ieee802154_radio_confirm_set_trx_state(openwsn_radio.dev) ==
-EAGAIN) {}
}
}
void radio_loadPacket(uint8_t *packet, uint16_t len)
{
/* OpenWSN `len` accounts for the FCS field which is set by default by
netdev, so remove from the actual packet `len` */
iolist_t pkt = {
.iol_base = (void *)packet,
.iol_len = (size_t)(len - IEEE802154_FCS_LEN),
};
if (ieee802154_radio_write(openwsn_radio.dev, &pkt) < 0) {
LOG_ERROR("[openwsn/radio]: couldn't load pkt\n");
}
}
void radio_txEnable(void)
{
int ret = ieee802154_radio_request_set_trx_state(openwsn_radio.dev,
IEEE802154_TRX_STATE_TX_ON);
if (ret) {
LOG_ERROR("[openwsn/radio]: request_set_trx_state failed %s\n",
__FUNCTION__);
}
else {
while (ieee802154_radio_confirm_set_trx_state(openwsn_radio.dev) ==
-EAGAIN) {}
debugpins_radio_set();
leds_radio_on();
}
}
void radio_txNow(void)
{
int ret = ieee802154_radio_request_transmit(openwsn_radio.dev);
if (ret) {
LOG_ERROR("[openwsn/radio]: request_set_trx_state failed %s\n",
__FUNCTION__);
}
else {
/* Trigger startFrame manually if no IEEE802154_CAP_IRQ_TX_START */
if (!ieee802154_radio_has_irq_tx_start(openwsn_radio.dev)) {
debugpins_isr_set();
_txrx_event_capture_time = sctimer_readCounter();
debugpins_isr_clr();
openwsn_radio.startFrame_cb(_txrx_event_capture_time);
}
}
}
void radio_rxEnable(void)
{
int ret = ieee802154_radio_request_set_trx_state(openwsn_radio.dev,
IEEE802154_TRX_STATE_TRX_OFF);
if (ret) {
LOG_ERROR("[openwsn/radio]: request_set_trx_state failed %s\n",
__FUNCTION__);
}
else {
while (ieee802154_radio_confirm_set_trx_state(openwsn_radio.dev) ==
-EAGAIN) {}
debugpins_radio_set();
leds_radio_on();
}
}
void radio_rxNow(void)
{
int ret = ieee802154_radio_request_set_trx_state(openwsn_radio.dev,
IEEE802154_TRX_STATE_RX_ON);
if (ret) {
LOG_ERROR("[openwsn/radio]: request_set_trx_state failed %s\n",
__FUNCTION__);
}
else {
while (ieee802154_radio_confirm_set_trx_state(openwsn_radio.dev) ==
-EAGAIN) {}
}
}
void radio_getReceivedFrame(uint8_t *bufRead,
uint8_t *lenRead,
uint8_t maxBufLen,
int8_t *rssi,
uint8_t *lqi,
bool *crc)
{
ieee802154_rx_info_t rx_info;
size_t size = ieee802154_radio_read(openwsn_radio.dev, bufRead,
maxBufLen, &rx_info);
/* FCS is skipped by the radio-hal in the returned length, but
OpenWSN includes IEEE802154_FCS_LEN in its length value */
*lenRead = size + IEEE802154_FCS_LEN;
/* get rssi, lqi & crc */
*rssi = rx_info.rssi;
*lqi = rx_info.lqi;
/* only valid crc frames are currently accepted */
*crc = 1;
}

View File

@ -26,6 +26,7 @@
#include "leds.h"
#include "debugpins.h"
#include "sctimer.h"
#include "idmanager.h"
#include "net/netopt.h"
#include "net/ieee802154.h"
@ -34,6 +35,15 @@
#include "openwsn.h"
#include "openwsn_radio.h"
#ifdef MODULE_AT86RF2XX
#include "at86rf2xx.h"
#include "at86rf2xx_params.h"
#endif
#ifdef MODULE_CC2538_RF
#include "cc2538_rf.h"
#endif
#define LOG_LEVEL LOG_NONE
#include "log.h"
@ -44,9 +54,32 @@ static void _event_cb(netdev_t *dev, netdev_event_t event);
/* stores the NETDEV_EVENT_ISR capture time to tag the following NETDEV_EVENT */
static PORT_TIMER_WIDTH _txrx_event_capture_time = 0;
int openwsn_radio_init(netdev_t *netdev)
static void _set_addr(void)
{
assert(netdev);
netdev_t* dev = openwsn_radio.dev;
/* Initiate Id manager here and not in `openstack_init` function to allow
overriding the short id address before additional stack components are
initiated */
idmanager_init();
/* override 16b address to avoid short address collision */
uint8_t addr[IEEE802154_SHORT_ADDRESS_LEN];
dev->driver->get(dev, NETOPT_ADDRESS, addr, IEEE802154_SHORT_ADDRESS_LEN);
open_addr_t id;
id.type = ADDR_16B;
memcpy(&id.addr_16b, addr, IEEE802154_SHORT_ADDRESS_LEN);
idmanager_setMyID(&id);
/* override PANID */
id.type = ADDR_PANID;
uint16_t panid = OPENWSN_PANID;
memcpy(&id.addr_16b, &panid, IEEE802154_SHORT_ADDRESS_LEN);
idmanager_setMyID(&id);
}
int openwsn_radio_init(void *radio_dev)
{
assert(radio_dev);
netdev_t *netdev = (netdev_t *)radio_dev;
LOG_DEBUG("[openwsn/radio]: initialize riot-adaptation\n");
openwsn_radio.dev = netdev;
@ -89,6 +122,8 @@ int openwsn_radio_init(netdev_t *netdev)
uint16_t panid = OPENWSN_PANID;
netdev->driver->set(netdev, NETOPT_NID, &(panid), sizeof(uint16_t));
_set_addr();
return 0;
}

View File

@ -67,6 +67,15 @@ static uint32_t _prescaler;
static atomic_bool _enable;
#endif
#if RTT_MAX_VALUE < UINT32_MAX
/* If RTT_MAX_VALUE is smaller the UINT32_MAX then handle the remaining
bits here, sctimer is scheduled at least every slot (20ms) so no
overflow will be missed */
#define SCTIMER_RTT_EXTEND_MSB (1 << (32UL - __builtin_clz(RTT_MAX_VALUE)))
static atomic_uint_fast32_t _counter_msb;
static atomic_uint_fast32_t _now_last;
#endif
static sctimer_cbt sctimer_cb;
static void sctimer_isr_internal(void *arg)
@ -84,6 +93,10 @@ void sctimer_init(void)
{
rtt_init();
sctimer_cb = NULL;
#ifdef SCTIMER_RTT_EXTEND_MSB
atomic_store(&_counter_msb, 0);
atomic_store(&_now_last, 0);
#endif
#ifdef SCTIMER_TIME_DIVISION
_prescaler = 0;
_enable = false;
@ -115,12 +128,34 @@ uint32_t _update_val(uint32_t val, uint32_t now)
}
#endif
#ifdef SCTIMER_RTT_EXTEND_MSB
uint32_t _sctimer_extend(uint32_t now)
{
unsigned state = irq_disable();
uint32_t now_last = atomic_load(&_now_last);
uint32_t counter_msb = atomic_load(&_counter_msb);
if (now < now_last) {
/* account for overflow */
counter_msb += SCTIMER_RTT_EXTEND_MSB;
atomic_store(&_counter_msb, counter_msb);
}
atomic_store(&_now_last, now);
now += counter_msb;
irq_restore(state);
return now;
}
#endif
void sctimer_setCompare(uint32_t val)
{
unsigned state = irq_disable();
uint32_t now = rtt_get_counter();
#ifdef SCTIMER_RTT_EXTEND_MSB
now = _sctimer_extend(now);
#endif
#ifdef SCTIMER_TIME_DIVISION
val = _update_val(val, now);
#endif
@ -150,6 +185,10 @@ uint32_t sctimer_readCounter(void)
{
uint32_t now = rtt_get_counter();
#ifdef SCTIMER_RTT_EXTEND_MSB
now = _sctimer_extend(now);
#endif
#ifdef SCTIMER_TIME_DIVISION
now &= SCTIMER_TIME_DIVISION_MASK;
now = (now << SCTIMER_PRESCALER);

View File

@ -22,6 +22,7 @@
#ifndef OPENWSN_DEBUGPINS_PARAMS_H
#define OPENWSN_DEBUGPINS_PARAMS_H
#include "board.h"
#include "openwsn_debugpins.h"
#ifdef __cplusplus

View File

@ -34,29 +34,37 @@ extern "C" {
* @note On Nucleo boards the LED pin is shared with SPI -> don't use it!
* @{
*/
#ifndef OPENWSN_LEDPIN_ERROR
#if defined (LED0_PIN) && !defined(MODULE_BOARDS_COMMON_NUCLEO)
#define OPENWSN_LEDPIN_ERROR LED0_PIN
#else
#define OPENWSN_LEDPIN_ERROR GPIO_UNDEF
#endif
#endif
#ifndef OPENWSN_LEDPIN_SYNC
#ifdef LED1_PIN
#define OPENWSN_LEDPIN_SYNC LED1_PIN
#else
#define OPENWSN_LEDPIN_SYNC GPIO_UNDEF
#endif
#endif
#ifndef OPENWSN_LEDPIN_RADIO
#ifdef LED2_PIN
#define OPENWSN_LEDPIN_RADIO LED2_PIN
#else
#define OPENWSN_LEDPIN_RADIO GPIO_UNDEF
#endif
#endif
#ifndef OPENWSN_LEDPIN_DEBUG
#ifdef LED3_PIN
#define OPENWSN_LEDPIN_DEBUG LED3_PIN
#else
#define OPENWSN_LEDPIN_DEBUG GPIO_UNDEF
#endif
#endif
#ifndef OPENWSN_LED_ON_STATE
#define OPENWSN_LED_ON_STATE GPIO_LED_LOW

View File

@ -55,25 +55,30 @@ extern "C" {
#endif
#include "net/netdev.h"
#include "net/ieee802154/radio.h"
#include "radio.h"
/**
* @brief Initialize OpenWSN radio
*
* @param[in] netdev pointer to a netdev interface
* @param[in] radio_dev pointer to a dev interface
*
* @return PID of OpenWSN thread
* @return -1 on initialization error
*/
int openwsn_radio_init(netdev_t *netdev);
int openwsn_radio_init(void *radio_dev);
/**
* @brief OpenWSN radio variables structure
*/
typedef struct {
#if IS_ACTIVE(MODULE_OPENWSN_RADIO_NETDEV)
netdev_t *dev; /**< netdev device */
#else
ieee802154_dev_t *dev; /**< radio hal */
#endif
radio_capture_cbt startFrame_cb; /**< start of frame capture callback */
radio_capture_cbt endFrame_cb; /**< end of frame capture callback */
netdev_t *dev; /**< netdev device */
} openwsn_radio_t;
#ifdef __cplusplus

View File

@ -61,14 +61,14 @@ void scheduler_start(unsigned state)
/* wait for events */
event_t *event;
while ((event = event_wait_multi(_queues, TASKPRIO_MAX))) {
debugpins_task_clr();
debugpins_task_set();
event->handler(event);
/* remove from task list */
memarray_free(&_scheduler_vars.memarray, event);
#if SCHEDULER_DEBUG_ENABLE
scheduler_dbg.numTasksCur--;
#endif
debugpins_task_set();
debugpins_task_clr();
}
}

View File

@ -550,6 +550,9 @@ ifneq (,$(filter shell_commands,$(USEMODULE)))
USEMODULE += nimble_scanlist
USEMODULE += fmt
endif
ifneq (,$(filter openwsn_%,$(USEMODULE)))
USEMODULE += netif
endif
endif
ifneq (,$(filter posix_semaphore,$(USEMODULE)))

View File

@ -2,14 +2,33 @@ BOARD ?= iotlab-m3
include ../Makefile.tests_common
# list of arm boards that provide at86rf2xx radios, can't require it so
# add whitelist
# list of arm boards that provide at86rf2xx radios, cc2538_rf or nrf52840
# radios
BOARD_WHITELIST = \
adafruit-clue \
adafruit-itsybitsy-nrf52 \
arduino-nano-33-ble \
cc2538dk \
feather-nrf52840 \
firefly \
fox \
iotlab-m3 \
iotlab-a8-m3 \
nrf52840-mdk \
nrf52840dk \
nrf52840dongle \
omote \
openmote-b \
openmote-cc2538 \
particle-argon \
particle-boron \
particle-xenon \
samr21-xpro \
samr30-xpro \
reel \
remote-pa \
remote-reva \
remote-revb \
#
# OpenWSN Modules
@ -36,7 +55,7 @@ USEMODULE += openwsn_debugpins
ifneq (,$(filter openwsn_serial,$(USEMODULE)))
# Uncomment to use STDIO_UART_DEV as the uart for OpenWSN openserial
# USEMODULE += stdio_null
ifneq (,$(filter iotlab-m3 iotlab-a8-m3,$(BOARD)))
ifneq (,$(filter iotlab-% openmote-b,$(BOARD)))
USEMODULE += stdio_null
endif
# OpenWSN serial module can't handle data at more than 115200 bauds/s,
@ -66,11 +85,3 @@ USEMODULE += shell_commands
USEMODULE += ztimer_usec
include $(RIOTBASE)/Makefile.include
# We want the highest possible frequency set for periph_rtt, but not all
# platforms can configure this value. use highest possible RTT_FREQUENCY
# for platforms that allow it
ifneq (,$(filter stm32,$(CPU)))
RTT_FREQUENCY ?= RTT_MAX_FREQUENCY
CFLAGS += -DRTT_FREQUENCY=$(RTT_FREQUENCY)
endif