mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
tests/driver_at86rf2xx: rewrite without GNRC
This commit is contained in:
parent
3095afafd2
commit
9d3a546e1d
@ -1,11 +1,9 @@
|
|||||||
|
INCLUDES += -I$(APPDIR)
|
||||||
|
BOARD ?= samr21-xpro
|
||||||
|
|
||||||
include ../Makefile.tests_common
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
DISABLE_MODULE += auto_init_at86rf2xx
|
USEMODULE += test_utils_netdev_ieee802154_minimal
|
||||||
|
|
||||||
USEMODULE += od
|
|
||||||
USEMODULE += shell
|
|
||||||
USEMODULE += shell_commands
|
|
||||||
USEMODULE += ps
|
|
||||||
|
|
||||||
# define the driver to be used for selected boards
|
# define the driver to be used for selected boards
|
||||||
ifneq (,$(filter samr21-xpro,$(BOARD)))
|
ifneq (,$(filter samr21-xpro,$(BOARD)))
|
||||||
@ -24,4 +22,6 @@ DRIVER ?= at86rf231
|
|||||||
# include the selected driver
|
# include the selected driver
|
||||||
USEMODULE += $(DRIVER)
|
USEMODULE += $(DRIVER)
|
||||||
|
|
||||||
|
CFLAGS += -DEVENT_THREAD_STACKSIZE_DEFAULT=1024
|
||||||
|
|
||||||
include $(RIOTBASE)/Makefile.include
|
include $(RIOTBASE)/Makefile.include
|
||||||
|
@ -3,9 +3,8 @@ BOARD_INSUFFICIENT_MEMORY := \
|
|||||||
arduino-leonardo \
|
arduino-leonardo \
|
||||||
arduino-nano \
|
arduino-nano \
|
||||||
arduino-uno \
|
arduino-uno \
|
||||||
atmega328p \
|
|
||||||
atmega328p-xplained-mini \
|
atmega328p-xplained-mini \
|
||||||
nucleo-f031k6 \
|
atmega328p \
|
||||||
nucleo-l011k4 \
|
nucleo-l011k4 \
|
||||||
samd10-xmini \
|
samd10-xmini \
|
||||||
stm32f030f4-demo \
|
stm32f030f4-demo \
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
# About
|
# About
|
||||||
This is a manual test application for the AT86RF2xx radio driver
|
This is a manual test application for the AT86RF2xx radio driver.
|
||||||
|
|
||||||
For running this test, you need to connect/configure the following pins of your
|
For running this test, you need to connect/configure the following pins of your
|
||||||
radio device:
|
radio device:
|
||||||
- SPI MISO
|
- SPI MISO
|
||||||
- SPI MOSI
|
- SPI MOSI
|
||||||
- SPI CLK
|
- SPI CLK
|
||||||
- CS (ship select)
|
- CS (chip select)
|
||||||
- RESET
|
- RESET
|
||||||
- SLEEP
|
- SLEEP
|
||||||
- INT (external interrupt)
|
- INT (external interrupt)
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
For testing the radio driver you can use the netif and txtsnd shell commands
|
For testing the radio driver you can use the ifconfig and txtsnd shell commands
|
||||||
that are included in this application.
|
that are included in this application.
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) Freie Universität Berlin
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file
|
|
||||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
void print_addr(uint8_t *addr, size_t addr_len)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < addr_len; i++) {
|
|
||||||
if (i != 0) {
|
|
||||||
printf(":");
|
|
||||||
}
|
|
||||||
printf("%02x", (unsigned)addr[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
|
@ -1,335 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 Freie Universität Berlin
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file
|
|
||||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "at86rf2xx_internal.h"
|
|
||||||
#include "common.h"
|
|
||||||
#include "net/ieee802154.h"
|
|
||||||
#include "net/netdev/ieee802154.h"
|
|
||||||
#include "od.h"
|
|
||||||
#include "test_utils/expect.h"
|
|
||||||
|
|
||||||
#define _MAX_ADDR_LEN (8)
|
|
||||||
#define MAC_VECTOR_SIZE (2) /* mhr + payload */
|
|
||||||
|
|
||||||
static size_t _parse_addr(uint8_t *out, size_t out_len, const char *in);
|
|
||||||
static int send(int iface, le_uint16_t dst_pan, uint8_t *dst_addr,
|
|
||||||
size_t dst_len, char *data);
|
|
||||||
|
|
||||||
int ifconfig_list(int idx)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
netdev_ieee802154_t *dev = &devs[idx].netdev;
|
|
||||||
|
|
||||||
int (*get)(netdev_t *, netopt_t, void *, size_t) = dev->netdev.driver->get;
|
|
||||||
netopt_enable_t enable_val;
|
|
||||||
uint16_t u16_val;
|
|
||||||
|
|
||||||
printf("Iface %3d HWaddr: ", idx);
|
|
||||||
print_addr(dev->short_addr, IEEE802154_SHORT_ADDRESS_LEN);
|
|
||||||
printf(", Long HWaddr: ");
|
|
||||||
print_addr(dev->long_addr, IEEE802154_LONG_ADDRESS_LEN);
|
|
||||||
printf(", PAN: 0x%04x", dev->pan);
|
|
||||||
|
|
||||||
res = get(&dev->netdev, NETOPT_ADDR_LEN, &u16_val, sizeof(u16_val));
|
|
||||||
if (res < 0) {
|
|
||||||
puts("(err)");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf("\n Address length: %u", (unsigned)u16_val);
|
|
||||||
|
|
||||||
res = get(&dev->netdev, NETOPT_SRC_LEN, &u16_val, sizeof(u16_val));
|
|
||||||
if (res < 0) {
|
|
||||||
puts("(err)");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf(", Source address length: %u", (unsigned)u16_val);
|
|
||||||
|
|
||||||
res = get(&dev->netdev, NETOPT_MAX_PDU_SIZE, &u16_val,
|
|
||||||
sizeof(u16_val));
|
|
||||||
if (res < 0) {
|
|
||||||
puts("(err)");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf(", Max.Payload: %u", (unsigned)u16_val);
|
|
||||||
printf("\n Channel: %u", dev->chan);
|
|
||||||
|
|
||||||
res = get(&dev->netdev, NETOPT_CHANNEL_PAGE, &u16_val, sizeof(u16_val));
|
|
||||||
if (res < 0) {
|
|
||||||
puts("(err)");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf(", Ch.page: %u", (unsigned)u16_val);
|
|
||||||
|
|
||||||
res = get(&dev->netdev, NETOPT_TX_POWER, &u16_val, sizeof(u16_val));
|
|
||||||
if (res < 0) {
|
|
||||||
puts("(err)");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
printf(", TXPower: %d dBm", (int)u16_val);
|
|
||||||
res = get(&dev->netdev, NETOPT_IS_WIRED, &u16_val, sizeof(u16_val));
|
|
||||||
if (res < 0) {
|
|
||||||
puts(", wireless");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
puts(", wired");
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(" ");
|
|
||||||
res = get(&dev->netdev, NETOPT_PRELOADING, &enable_val,
|
|
||||||
sizeof(netopt_enable_t));
|
|
||||||
if ((res > 0) && (enable_val == NETOPT_ENABLE)) {
|
|
||||||
printf(" PRELOAD");
|
|
||||||
}
|
|
||||||
res = get(&dev->netdev, NETOPT_AUTOACK, &enable_val,
|
|
||||||
sizeof(netopt_enable_t));
|
|
||||||
if ((res > 0) && (enable_val == NETOPT_ENABLE)) {
|
|
||||||
printf(" AUTOACK");
|
|
||||||
}
|
|
||||||
res = get(&dev->netdev, NETOPT_RAWMODE, &enable_val,
|
|
||||||
sizeof(netopt_enable_t));
|
|
||||||
if ((res > 0) && (enable_val == NETOPT_ENABLE)) {
|
|
||||||
printf(" RAW");
|
|
||||||
}
|
|
||||||
res = get(&dev->netdev, NETOPT_AUTOCCA, &enable_val,
|
|
||||||
sizeof(netopt_enable_t));
|
|
||||||
if ((res > 0) && (enable_val == NETOPT_ENABLE)) {
|
|
||||||
printf(" AUTOCCA");
|
|
||||||
}
|
|
||||||
res = get(&dev->netdev, NETOPT_CSMA, &enable_val,
|
|
||||||
sizeof(netopt_enable_t));
|
|
||||||
if ((res > 0) && (enable_val == NETOPT_ENABLE)) {
|
|
||||||
printf(" CSMA");
|
|
||||||
}
|
|
||||||
puts("");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ifconfig(int argc, char **argv)
|
|
||||||
{
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
for (unsigned int i = 0; i < AT86RF2XX_NUM; i++) {
|
|
||||||
ifconfig_list(i);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void txtsnd_usage(char *cmd_name)
|
|
||||||
{
|
|
||||||
printf("usage: %s <iface> [<pan>] <addr> <text>\n", cmd_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
int txtsnd(int argc, char **argv)
|
|
||||||
{
|
|
||||||
char *text;
|
|
||||||
uint8_t addr[_MAX_ADDR_LEN];
|
|
||||||
int iface, idx = 2;
|
|
||||||
size_t res;
|
|
||||||
le_uint16_t pan = { 0 };
|
|
||||||
|
|
||||||
switch (argc) {
|
|
||||||
case 4:
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
res = _parse_addr((uint8_t *)&pan, sizeof(pan), argv[idx++]);
|
|
||||||
if ((res == 0) || (res > sizeof(pan))) {
|
|
||||||
txtsnd_usage(argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
pan.u16 = byteorder_swaps(pan.u16);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
txtsnd_usage(argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
iface = atoi(argv[1]);
|
|
||||||
res = _parse_addr(addr, sizeof(addr), argv[idx++]);
|
|
||||||
if (res == 0) {
|
|
||||||
txtsnd_usage(argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
text = argv[idx++];
|
|
||||||
return send(iface, pan, addr, res, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int _dehex(char c, int default_)
|
|
||||||
{
|
|
||||||
if ('0' <= c && c <= '9') {
|
|
||||||
return c - '0';
|
|
||||||
}
|
|
||||||
else if ('A' <= c && c <= 'F') {
|
|
||||||
return c - 'A' + 10;
|
|
||||||
}
|
|
||||||
else if ('a' <= c && c <= 'f') {
|
|
||||||
return c - 'a' + 10;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return default_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t _parse_addr(uint8_t *out, size_t out_len, const char *in)
|
|
||||||
{
|
|
||||||
const char *end_str = in;
|
|
||||||
uint8_t *out_end = out;
|
|
||||||
size_t count = 0;
|
|
||||||
int assert_cell = 1;
|
|
||||||
|
|
||||||
if (!in || !*in) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
while (end_str[1]) {
|
|
||||||
++end_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (end_str >= in) {
|
|
||||||
int a = 0, b = _dehex(*end_str--, -1);
|
|
||||||
if (b < 0) {
|
|
||||||
if (assert_cell) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert_cell = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert_cell = 0;
|
|
||||||
|
|
||||||
if (end_str >= in) {
|
|
||||||
a = _dehex(*end_str--, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++count > out_len) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*out_end++ = (a << 4) | b;
|
|
||||||
}
|
|
||||||
if (assert_cell) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* out is reversed */
|
|
||||||
|
|
||||||
while (out < --out_end) {
|
|
||||||
uint8_t tmp = *out_end;
|
|
||||||
*out_end = *out;
|
|
||||||
*out++ = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int send(int iface, le_uint16_t dst_pan, uint8_t *dst, size_t dst_len,
|
|
||||||
char *data)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
netdev_ieee802154_t *dev;
|
|
||||||
uint8_t *src;
|
|
||||||
size_t src_len;
|
|
||||||
uint8_t mhr[IEEE802154_MAX_HDR_LEN];
|
|
||||||
uint8_t flags;
|
|
||||||
le_uint16_t src_pan;
|
|
||||||
|
|
||||||
if (((unsigned)iface) > (AT86RF2XX_NUM - 1)) {
|
|
||||||
printf("txtsnd: %d is not an interface\n", iface);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
iolist_t iol_data = {
|
|
||||||
.iol_base = data,
|
|
||||||
.iol_len = strlen(data)
|
|
||||||
};
|
|
||||||
|
|
||||||
dev = &devs[iface].netdev;
|
|
||||||
flags = (uint8_t)(dev->flags & NETDEV_IEEE802154_SEND_MASK);
|
|
||||||
flags |= IEEE802154_FCF_TYPE_DATA;
|
|
||||||
src_pan = byteorder_btols(byteorder_htons(dev->pan));
|
|
||||||
if (dst_pan.u16 == 0) {
|
|
||||||
dst_pan = src_pan;
|
|
||||||
}
|
|
||||||
if (dev->flags & NETDEV_IEEE802154_SRC_MODE_LONG) {
|
|
||||||
src_len = 8;
|
|
||||||
src = dev->long_addr;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
src_len = 2;
|
|
||||||
src = dev->short_addr;
|
|
||||||
}
|
|
||||||
/* fill MAC header, seq should be set by device */
|
|
||||||
if ((res = ieee802154_set_frame_hdr(mhr, src, src_len,
|
|
||||||
dst, dst_len,
|
|
||||||
src_pan, dst_pan,
|
|
||||||
flags, dev->seq++)) < 0) {
|
|
||||||
puts("txtsnd: Error preperaring frame");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
iolist_t iol_hdr = {
|
|
||||||
.iol_next = &iol_data,
|
|
||||||
.iol_base = mhr,
|
|
||||||
.iol_len = (size_t)res
|
|
||||||
};
|
|
||||||
|
|
||||||
res = dev->netdev.driver->send(&dev->netdev, &iol_hdr);
|
|
||||||
if (res < 0) {
|
|
||||||
puts("txtsnd: Error on sending");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("txtsnd: send %u bytes to ", (unsigned)iol_data.iol_len);
|
|
||||||
print_addr(dst, dst_len);
|
|
||||||
printf(" (PAN: ");
|
|
||||||
print_addr((uint8_t *)&dst_pan, sizeof(dst_pan));
|
|
||||||
puts(")");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if AT86RF2XX_RANDOM_NUMBER_GENERATOR
|
|
||||||
void random_net_api(uint8_t idx, uint32_t *value)
|
|
||||||
{
|
|
||||||
netdev_ieee802154_t *dev = &devs[idx].netdev;
|
|
||||||
int retval = dev->netdev.driver->get(&dev->netdev, NETOPT_RANDOM,
|
|
||||||
value, sizeof(uint32_t));
|
|
||||||
if (retval < 0) {
|
|
||||||
printf("get(NETOPT_RANDOM) failed: %s\n", strerror(-retval));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
expect(retval == sizeof(*value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int random_by_at86rf2xx(int argc, char **argv)
|
|
||||||
{
|
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
|
||||||
for (unsigned int i = 0; i < AT86RF2XX_NUM; i++) {
|
|
||||||
uint32_t test = 0;
|
|
||||||
at86rf2xx_get_random(&devs[i], (uint8_t *)&test, sizeof(test));
|
|
||||||
printf("Random number for device %u via native API: %" PRIx32 "\n", i, test);
|
|
||||||
test = 0;
|
|
||||||
random_net_api(i, &test);
|
|
||||||
printf("Random number for device %u via netopt: %" PRIx32 "\n", i, test);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/** @} */
|
|
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 Martine Lenders <mlenders@inf.fu-berlin.de>
|
|
||||||
*
|
|
||||||
* 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 tests
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file
|
|
||||||
* @brief Common header for at86rf2xx tests
|
|
||||||
*
|
|
||||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
|
||||||
*/
|
|
||||||
#ifndef COMMON_H
|
|
||||||
#define COMMON_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "at86rf2xx.h"
|
|
||||||
#include "at86rf2xx_params.h"
|
|
||||||
#include "net/netdev.h"
|
|
||||||
#include "kernel_defines.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Application-internal functions and variables for at86rf2xx tests
|
|
||||||
* @internal
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define AT86RF2XX_NUM ARRAY_SIZE(at86rf2xx_params)
|
|
||||||
|
|
||||||
extern at86rf2xx_t devs[AT86RF2XX_NUM];
|
|
||||||
|
|
||||||
void recv(netdev_t *dev);
|
|
||||||
int ifconfig(int argc, char **argv);
|
|
||||||
int txtsnd(int argc, char **argv);
|
|
||||||
#if AT86RF2XX_RANDOM_NUMBER_GENERATOR
|
|
||||||
int random_by_at86rf2xx(int argc, char **argv);
|
|
||||||
#endif
|
|
||||||
void print_addr(uint8_t *addr, size_t addr_len);
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* COMMON_H */
|
|
||||||
/** @} */
|
|
36
tests/driver_at86rf2xx/init_dev.h
Normal file
36
tests/driver_at86rf2xx/init_dev.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 HAW Hamburg
|
||||||
|
*
|
||||||
|
* 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 tests
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Device-specific test header file AT86RF2XX IEEE 802.15.4 device driver
|
||||||
|
*
|
||||||
|
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||||
|
*/
|
||||||
|
#ifndef INIT_DEV_H
|
||||||
|
#define INIT_DEV_H
|
||||||
|
|
||||||
|
#include "at86rf2xx_params.h"
|
||||||
|
#include "kernel_defines.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AT86RF2XX_NUM ARRAY_SIZE(at86rf2xx_params)
|
||||||
|
#define NETDEV_IEEE802154_MINIMAL_NUMOF AT86RF2XX_NUM
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* INIT_DEV_H */
|
||||||
|
/** @} */
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 Freie Universität Berlin
|
* Copyright (C) 2022 HAW Hamburg
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -11,110 +11,92 @@
|
|||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
* @brief Test application for AT86RF2xx network device driver
|
* @brief Test application for AT86RF2XX IEEE 802.15.4 device driver
|
||||||
*
|
*
|
||||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
* @author Leandro Lanzieri <leandro.lanzieri@haw-hamburg.de>
|
||||||
*
|
*
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "net/netdev.h"
|
#include "at86rf2xx.h"
|
||||||
|
#include "at86rf2xx_params.h"
|
||||||
|
#include "at86rf2xx_internal.h"
|
||||||
|
#include "init_dev.h"
|
||||||
|
#include "net/ieee802154.h"
|
||||||
|
#include "net/netdev/ieee802154.h"
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
#include "thread.h"
|
#include "test_utils/netdev_ieee802154_minimal.h"
|
||||||
#include "xtimer.h"
|
#include "test_utils/expect.h"
|
||||||
|
|
||||||
#include "common.h"
|
static at86rf2xx_t at86rf2xx[AT86RF2XX_NUM];
|
||||||
|
|
||||||
#define _STACKSIZE (THREAD_STACKSIZE_DEFAULT + THREAD_EXTRA_STACKSIZE_PRINTF)
|
|
||||||
#define MSG_TYPE_ISR (0x3456)
|
|
||||||
|
|
||||||
static char stack[_STACKSIZE];
|
|
||||||
static kernel_pid_t _recv_pid;
|
|
||||||
|
|
||||||
at86rf2xx_t devs[AT86RF2XX_NUM];
|
|
||||||
|
|
||||||
static const shell_command_t shell_commands[] = {
|
|
||||||
{ "ifconfig", "Configure netdev", ifconfig },
|
|
||||||
{ "txtsnd", "Send IEEE 802.15.4 packet", txtsnd },
|
|
||||||
#if AT86RF2XX_RANDOM_NUMBER_GENERATOR
|
#if AT86RF2XX_RANDOM_NUMBER_GENERATOR
|
||||||
{ "random", "Get a value from Random Number Generator", random_by_at86rf2xx },
|
void random_net_api(uint8_t idx, uint32_t *value)
|
||||||
#endif
|
|
||||||
{ NULL, NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void _event_cb(netdev_t *dev, netdev_event_t event)
|
|
||||||
{
|
{
|
||||||
if (event == NETDEV_EVENT_ISR) {
|
netdev_ieee802154_t *dev = &at86rf2xx[idx].netdev;
|
||||||
msg_t msg;
|
dev->netdev.driver->get(&dev->netdev, NETOPT_RANDOM, value, sizeof(uint32_t));
|
||||||
|
int retval = dev->netdev.driver->get(&dev->netdev, NETOPT_RANDOM,
|
||||||
msg.type = MSG_TYPE_ISR;
|
value, sizeof(uint32_t));
|
||||||
msg.content.ptr = dev;
|
if (retval < 0) {
|
||||||
|
printf("get(NETOPT_RANDOM) failed: %s\n", strerror(-retval));
|
||||||
if (msg_send(&msg, _recv_pid) <= 0) {
|
|
||||||
puts("gnrc_netdev: possibly lost interrupt.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
switch (event) {
|
expect(retval == sizeof(*value));
|
||||||
case NETDEV_EVENT_RX_COMPLETE:
|
|
||||||
{
|
|
||||||
recv(dev);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
puts("Unexpected event received");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *_recv_thread(void *arg)
|
int random_by_at86rf2xx(int argc, char **argv)
|
||||||
{
|
{
|
||||||
(void)arg;
|
(void)argc;
|
||||||
while (1) {
|
(void)argv;
|
||||||
msg_t msg;
|
for (unsigned int i = 0; i < AT86RF2XX_NUM; i++) {
|
||||||
msg_receive(&msg);
|
uint32_t test = 0;
|
||||||
if (msg.type == MSG_TYPE_ISR) {
|
at86rf2xx_get_random(&at86rf2xx[i], (uint8_t *)&test, sizeof(test));
|
||||||
netdev_t *dev = msg.content.ptr;
|
printf("Random number for device %u via native API: %" PRIx32 "\n", i, test);
|
||||||
dev->driver->isr(dev);
|
test = 0;
|
||||||
|
random_net_api(i, &test);
|
||||||
|
printf("Random number for device %u via netopt: %" PRIx32 "\n", i, test);
|
||||||
}
|
}
|
||||||
else {
|
return 0;
|
||||||
puts("unexpected message type");
|
}
|
||||||
|
|
||||||
|
static const shell_command_t shell_commands[] = {
|
||||||
|
{ "random", "Get a value from Random Number Generator", random_by_at86rf2xx },
|
||||||
|
{ NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int netdev_ieee802154_minimal_init_devs(netdev_event_cb_t cb) {
|
||||||
|
|
||||||
|
puts("Initializing AT86RF2XX devices");
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < AT86RF2XX_NUM; i++) {
|
||||||
|
printf("%d out of %d\n", i + 1, AT86RF2XX_NUM);
|
||||||
|
/* setup the specific driver */
|
||||||
|
at86rf2xx_setup(&at86rf2xx[i], &at86rf2xx_params[i], i);
|
||||||
|
|
||||||
|
/* set the application-provided callback */
|
||||||
|
at86rf2xx[i].netdev.netdev.event_callback = cb;
|
||||||
|
|
||||||
|
/* initialize the device driver */
|
||||||
|
int res = at86rf2xx[i].netdev.netdev.driver->init(&at86rf2xx[i].netdev.netdev);
|
||||||
|
if (res != 0) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
puts("AT86RF2xx device driver test");
|
puts("Test application for AT86RF2XX IEEE 802.15.4 device driver");
|
||||||
unsigned dev_success = 0;
|
|
||||||
for (unsigned i = 0; i < AT86RF2XX_NUM; i++) {
|
|
||||||
const at86rf2xx_params_t *p = &at86rf2xx_params[i];
|
|
||||||
netdev_t *dev = &devs[i].netdev.netdev;
|
|
||||||
|
|
||||||
printf("Initializing AT86RF2xx radio at SPI_%d\n", p->spi);
|
int res = netdev_ieee802154_minimal_init();
|
||||||
at86rf2xx_setup(&devs[i], p, i);
|
if (res) {
|
||||||
dev->event_callback = _event_cb;
|
puts("Error initializing devices");
|
||||||
if (dev->driver->init(dev) < 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dev_success++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dev_success) {
|
|
||||||
puts("No device could be initialized");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
_recv_pid = thread_create(stack, sizeof(stack), THREAD_PRIORITY_MAIN - 1,
|
|
||||||
THREAD_CREATE_STACKTEST, _recv_thread, NULL,
|
|
||||||
"recv_thread");
|
|
||||||
|
|
||||||
if (_recv_pid <= KERNEL_PID_UNDEF) {
|
|
||||||
puts("Creation of receiver thread failed");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +104,11 @@ int main(void)
|
|||||||
puts("Initialization successful - starting the shell now");
|
puts("Initialization successful - starting the shell now");
|
||||||
|
|
||||||
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||||
|
#if AT86RF2XX_RANDOM_NUMBER_GENERATOR
|
||||||
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||||
|
#else
|
||||||
|
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) Freie Universität Berlin
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @file
|
|
||||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "at86rf2xx.h"
|
|
||||||
#include "od.h"
|
|
||||||
#include "net/ieee802154.h"
|
|
||||||
#include "net/netdev.h"
|
|
||||||
|
|
||||||
#include "common.h"
|
|
||||||
|
|
||||||
#define MAX_LINE (80)
|
|
||||||
|
|
||||||
static uint8_t buffer[AT86RF2XX_MAX_PKT_LENGTH];
|
|
||||||
|
|
||||||
void recv(netdev_t *dev)
|
|
||||||
{
|
|
||||||
uint8_t src[IEEE802154_LONG_ADDRESS_LEN], dst[IEEE802154_LONG_ADDRESS_LEN];
|
|
||||||
size_t mhr_len, data_len, src_len, dst_len;
|
|
||||||
netdev_ieee802154_rx_info_t rx_info;
|
|
||||||
le_uint16_t src_pan, dst_pan;
|
|
||||||
|
|
||||||
putchar('\n');
|
|
||||||
data_len = dev->driver->recv(dev, buffer, sizeof(buffer), &rx_info);
|
|
||||||
mhr_len = ieee802154_get_frame_hdr_len(buffer);
|
|
||||||
if (mhr_len == 0) {
|
|
||||||
puts("Unexpected MHR for incoming packet");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dst_len = ieee802154_get_dst(buffer, dst, &dst_pan);
|
|
||||||
src_len = ieee802154_get_src(buffer, src, &src_pan);
|
|
||||||
switch (buffer[0] & IEEE802154_FCF_TYPE_MASK) {
|
|
||||||
case IEEE802154_FCF_TYPE_BEACON:
|
|
||||||
puts("BEACON");
|
|
||||||
break;
|
|
||||||
case IEEE802154_FCF_TYPE_DATA:
|
|
||||||
puts("DATA");
|
|
||||||
break;
|
|
||||||
case IEEE802154_FCF_TYPE_ACK:
|
|
||||||
puts("ACK");
|
|
||||||
break;
|
|
||||||
case IEEE802154_FCF_TYPE_MACCMD:
|
|
||||||
puts("MACCMD");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
puts("UNKNOWN");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("Dest. PAN: 0x%04x, Dest. addr.: ",
|
|
||||||
byteorder_ltohs(dst_pan));
|
|
||||||
print_addr(dst, dst_len);
|
|
||||||
printf("\nSrc. PAN: 0x%04x, Src. addr.: ",
|
|
||||||
byteorder_ltohs(src_pan));
|
|
||||||
print_addr(src, src_len);
|
|
||||||
printf("\nSecurity: ");
|
|
||||||
if (buffer[0] & IEEE802154_FCF_SECURITY_EN) {
|
|
||||||
printf("1, ");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("0, ");
|
|
||||||
}
|
|
||||||
printf("Frame pend.: ");
|
|
||||||
if (buffer[0] & IEEE802154_FCF_FRAME_PEND) {
|
|
||||||
printf("1, ");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("0, ");
|
|
||||||
}
|
|
||||||
printf("ACK req.: ");
|
|
||||||
if (buffer[0] & IEEE802154_FCF_ACK_REQ) {
|
|
||||||
printf("1, ");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf("0, ");
|
|
||||||
}
|
|
||||||
printf("PAN comp.: ");
|
|
||||||
if (buffer[0] & IEEE802154_FCF_PAN_COMP) {
|
|
||||||
puts("1");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
puts("0");
|
|
||||||
}
|
|
||||||
printf("Version: ");
|
|
||||||
printf("%u, ", (unsigned)((buffer[1] & IEEE802154_FCF_VERS_MASK) >> 4));
|
|
||||||
printf("Seq.: %u\n", (unsigned)ieee802154_get_seq(buffer));
|
|
||||||
od_hex_dump(buffer + mhr_len, data_len - mhr_len, 0);
|
|
||||||
printf("txt: ");
|
|
||||||
for (size_t i = mhr_len; i < data_len; i++) {
|
|
||||||
if ((buffer[i] > 0x1F) && (buffer[i] < 0x80)) {
|
|
||||||
putchar((char)buffer[i]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
putchar('?');
|
|
||||||
}
|
|
||||||
if (((((i - mhr_len) + 1) % (MAX_LINE - sizeof("txt: "))) == 1) &&
|
|
||||||
(i - mhr_len) != 0) {
|
|
||||||
printf("\n ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
printf("RSSI: %i, LQI: %u\n\n", rx_info.rssi, rx_info.lqi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
|
Loading…
Reference in New Issue
Block a user