cpu/nrf51: ported nrmin radio driver to netdev2
parent
e224cf8de8
commit
36317c56f3
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_nrf51822_nrfmin_gnrc GNRC adapter for nrfmin
|
||||
* @ingroup drivers_nrf51822_nrfmin
|
||||
* @brief Minimal driver for the NRF51 radio
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief GNRC adapter for nrfmin devices (e.g. nRF5x radios)
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef NRFMIN_GNRC_H_
|
||||
#define NRFMIN_GNRC_H_
|
||||
|
||||
#include "nrfmin.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize the nrfmin GNRC adapter, also takes care of the nrfmin
|
||||
* driver setup
|
||||
*
|
||||
* As we have never more than 1 nrfmin device on a board, we can make some
|
||||
* simplifications when it come to allocating device descriptors and adapter
|
||||
* data structures -> we do this right in the driver/adapter code, so this
|
||||
* function can be called from auto_init as is, without the need for external
|
||||
* memory allocation.
|
||||
*/
|
||||
void gnrc_netdev2_nrfmin_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NRFMIN_GNRC_H_ */
|
||||
/** @} */
|
@ -1,3 +1,3 @@
|
||||
MODULE = radio_nrfmin
|
||||
MODULE = nrfmin
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_nrf51_nrfmin
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief GNRC adapter for the nrfmin radio driver
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
#include "net/gnrc/netdev2.h"
|
||||
|
||||
#include "nrfmin_gnrc.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* @brief Definition of default thread priority and stacksize
|
||||
* @{
|
||||
*/
|
||||
#ifndef NRFMIN_GNRC_THREAD_PRIO
|
||||
#define NRFMIN_GNRC_THREAD_PRIO GNRC_NETDEV2_MAC_PRIO
|
||||
#endif
|
||||
|
||||
#ifndef NRFMIN_GNRC_STACKSIZE
|
||||
#define NRFMIN_GNRC_STACKSIZE THREAD_STACKSIZE_DEFAULT
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
#define BCAST (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)
|
||||
|
||||
/**
|
||||
* @brief Allocate the stack for the GNRC netdev2 thread to run in
|
||||
*/
|
||||
static char stack[NRFMIN_GNRC_STACKSIZE];
|
||||
|
||||
/**
|
||||
* @brief Allocate the GNRC netdev2 data structure.
|
||||
*/
|
||||
static gnrc_netdev2_t plug;
|
||||
|
||||
|
||||
static int hdr_netif_to_nrfmin(nrfmin_hdr_t *nrfmin, gnrc_pktsnip_t *pkt)
|
||||
{
|
||||
gnrc_netif_hdr_t *netif = (gnrc_netif_hdr_t *)pkt->data;
|
||||
|
||||
if (!(netif->flags & BCAST) && (netif->dst_l2addr_len != 2)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nrfmin->len = gnrc_pkt_len(pkt->next) + NRFMIN_HDR_LEN;
|
||||
if (netif->flags & BCAST) {
|
||||
nrfmin->dst_addr = NRFMIN_ADDR_BCAST;
|
||||
}
|
||||
else {
|
||||
memcpy(&nrfmin->dst_addr, gnrc_netif_hdr_get_dst_addr(netif), 2);
|
||||
}
|
||||
nrfmin->src_addr = nrfmin_get_addr();
|
||||
if (pkt->next) {
|
||||
nrfmin->proto = (uint8_t)pkt->next->type;
|
||||
}
|
||||
else {
|
||||
nrfmin->proto = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nrfmin_gnrc_send(gnrc_netdev2_t *dev, gnrc_pktsnip_t *pkt)
|
||||
{
|
||||
int res;
|
||||
struct iovec *vec;
|
||||
size_t vec_len;
|
||||
gnrc_pktsnip_t *vec_snip;
|
||||
nrfmin_hdr_t nrfmin_hdr;
|
||||
|
||||
assert(pkt);
|
||||
|
||||
if (pkt->type != GNRC_NETTYPE_NETIF) {
|
||||
DEBUG("[nrfmin_gnrc] send: first header is not generic netif header\n");
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
/* build the nrfmin header from the generic netif header */
|
||||
res = hdr_netif_to_nrfmin(&nrfmin_hdr, pkt);
|
||||
if (res < 0) {
|
||||
DEBUG("[nrfmin_gnrc] send: failed to build nrfmin header\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* create iovec of data */
|
||||
vec_snip = gnrc_pktbuf_get_iovec(pkt, &vec_len);
|
||||
if (vec_snip == NULL) {
|
||||
DEBUG("[nrfmin_gnrc] send: failed to create IO vector\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
/* link first entry of the vector to the nrfmin header */
|
||||
vec = (struct iovec *)vec_snip->data;
|
||||
vec[0].iov_base = &nrfmin_hdr;
|
||||
vec[0].iov_len = NRFMIN_HDR_LEN;
|
||||
|
||||
/* and finally send out the data and release the packet */
|
||||
res = dev->dev->driver->send(dev->dev, vec, vec_len);
|
||||
gnrc_pktbuf_release(vec_snip);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gnrc_pktsnip_t *nrfmin_gnrc_recv(gnrc_netdev2_t *dev)
|
||||
{
|
||||
int pktsize;
|
||||
nrfmin_hdr_t *nrfmin;
|
||||
gnrc_netif_hdr_t *netif;
|
||||
gnrc_pktsnip_t *pkt_snip;
|
||||
gnrc_pktsnip_t *hdr_snip;
|
||||
gnrc_pktsnip_t *netif_snip;
|
||||
|
||||
/* get the size of the new packet */
|
||||
pktsize = nrfmin_dev.driver->recv(NULL, NULL, 0, NULL);
|
||||
if (pktsize <= 0) {
|
||||
DEBUG("[nrfmin_gnrc] recv: error: tried to read empty packet\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* allocate space in the packet buffer */
|
||||
pkt_snip = gnrc_pktbuf_add(NULL, NULL, pktsize, GNRC_NETTYPE_UNDEF);
|
||||
if (pkt_snip == NULL) {
|
||||
DEBUG("[nrfmin_gnrc] recv: unable to allocate pktsnip\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read the incoming data into the packet buffer */
|
||||
nrfmin_dev.driver->recv(NULL, pkt_snip->data, pktsize, NULL);
|
||||
|
||||
/* now we mark the nrfmin header */
|
||||
hdr_snip = gnrc_pktbuf_mark(pkt_snip, NRFMIN_HDR_LEN, GNRC_NETTYPE_UNDEF);
|
||||
if (hdr_snip == NULL) {
|
||||
DEBUG("[nrfmin_gnrc] recv: unable to mark the nrfmin header\n");
|
||||
gnrc_pktbuf_release(pkt_snip);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* allocate the generic netif header and populate it with data from the
|
||||
nrfmin header */
|
||||
nrfmin = (nrfmin_hdr_t *)hdr_snip->data;
|
||||
netif_snip = gnrc_netif_hdr_build((uint8_t *)&nrfmin->src_addr, 2,
|
||||
(uint8_t *)&nrfmin->dst_addr, 2);
|
||||
if (netif_snip == NULL) {
|
||||
DEBUG("[nrfmin_gnrc] recv: unable to allocate netif header\n");
|
||||
gnrc_pktbuf_release(pkt_snip);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
netif = (gnrc_netif_hdr_t *)netif_snip->data;
|
||||
if (nrfmin->dst_addr == NRFMIN_ADDR_BCAST) {
|
||||
netif->flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST;
|
||||
}
|
||||
netif->lqi = 0;
|
||||
netif->rssi = 0;
|
||||
netif->if_pid = plug.pid;
|
||||
pkt_snip->type = nrfmin->proto;
|
||||
|
||||
/* finally: remove the nrfmin header and append the netif header */
|
||||
gnrc_pktbuf_remove_snip(pkt_snip, hdr_snip);
|
||||
LL_APPEND(pkt_snip, netif_snip);
|
||||
|
||||
return pkt_snip;
|
||||
}
|
||||
|
||||
void nrfmin_gnrc_init(void)
|
||||
{
|
||||
/* setup the NRFMIN driver */
|
||||
nrfmin_setup();
|
||||
|
||||
/* initialize the GNRC plug struct */
|
||||
plug.send = nrfmin_gnrc_send;
|
||||
plug.recv = nrfmin_gnrc_recv;
|
||||
plug.dev = &nrfmin_dev;
|
||||
|
||||
gnrc_netdev2_init(stack, sizeof(stack),
|
||||
NRFMIN_GNRC_THREAD_PRIO,
|
||||
"nrfmin", &plug);
|
||||
}
|
Loading…
Reference in New Issue