From 274318b669d1f2937840c160b9e30c6813c84ec6 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Sat, 16 Jan 2016 19:44:47 +0100 Subject: [PATCH] at86rf2xx: port to netdev2 --- drivers/at86rf2xx/at86rf2xx.c | 52 +- drivers/at86rf2xx/at86rf2xx_netdev.c | 560 ++++++------------ drivers/at86rf2xx/include/at86rf2xx_netdev.h | 4 +- drivers/include/at86rf2xx.h | 52 +- drivers/include/net/netdev2.h | 24 +- .../netdev2_ieee802154/netdev2_ieee802154.c | 26 +- .../netdev2/gnrc_netdev2_ieee802154.c | 2 +- 7 files changed, 242 insertions(+), 478 deletions(-) diff --git a/drivers/at86rf2xx/at86rf2xx.c b/drivers/at86rf2xx/at86rf2xx.c index b194a1df32315..04d0b55aa5bd0 100644 --- a/drivers/at86rf2xx/at86rf2xx.c +++ b/drivers/at86rf2xx/at86rf2xx.c @@ -35,19 +35,9 @@ #include "debug.h" -static void _irq_handler(void *arg) -{ - msg_t msg; - at86rf2xx_t *dev = (at86rf2xx_t *) arg; - - /* tell driver thread about the interrupt */ - msg.type = GNRC_NETDEV_MSG_TYPE_EVENT; - msg_send(&msg, dev->mac_pid); -} - -int at86rf2xx_init(at86rf2xx_t *dev, spi_t spi, spi_speed_t spi_speed, - gpio_t cs_pin, gpio_t int_pin, - gpio_t sleep_pin, gpio_t reset_pin) +int at86rf2xx_setup(at86rf2xx_t *dev, spi_t spi, spi_speed_t spi_speed, + gpio_t cs_pin, gpio_t int_pin, gpio_t sleep_pin, + gpio_t reset_pin) { dev->driver = &at86rf2xx_driver; @@ -59,32 +49,8 @@ int at86rf2xx_init(at86rf2xx_t *dev, spi_t spi, spi_speed_t spi_speed, dev->reset_pin = reset_pin; dev->idle_state = AT86RF2XX_STATE_TRX_OFF; dev->state = AT86RF2XX_STATE_SLEEP; - /* initialise SPI */ spi_init_master(dev->spi, SPI_CONF_FIRST_RISING, spi_speed); - /* initialise GPIOs */ - gpio_init(dev->cs_pin, GPIO_DIR_OUT, GPIO_NOPULL); - gpio_set(dev->cs_pin); - gpio_init(dev->sleep_pin, GPIO_DIR_OUT, GPIO_NOPULL); - gpio_clear(dev->sleep_pin); - gpio_init(dev->reset_pin, GPIO_DIR_OUT, GPIO_NOPULL); - gpio_set(dev->reset_pin); - gpio_init_int(dev->int_pin, GPIO_NOPULL, GPIO_RISING, _irq_handler, dev); - - /* make sure device is not sleeping, so we can query part number */ - at86rf2xx_assert_awake(dev); - - /* test if the SPI is set up correctly and the device is responding */ - if (at86rf2xx_reg_read(dev, AT86RF2XX_REG__PART_NUM) != - AT86RF2XX_PARTNUM) { - DEBUG("[at86rf2xx] error: unable to read correct part number\n"); - return -1; - } - - /* reset device to default values and put it into RX state */ - at86rf2xx_reset(dev); - - return 0; } void at86rf2xx_reset(at86rf2xx_t *dev) @@ -219,20 +185,19 @@ void at86rf2xx_tx_prepare(at86rf2xx_t *dev) /* make sure ongoing transmissions are finished */ do { state = at86rf2xx_get_status(dev); - } - while (state == AT86RF2XX_STATE_BUSY_RX_AACK || - state == AT86RF2XX_STATE_BUSY_TX_ARET); + } while (state == AT86RF2XX_STATE_BUSY_RX_AACK || + state == AT86RF2XX_STATE_BUSY_TX_ARET); if (state != AT86RF2XX_STATE_TX_ARET_ON) { dev->idle_state = state; } at86rf2xx_set_state(dev, AT86RF2XX_STATE_TX_ARET_ON); - dev->frame_len = IEEE802154_FCS_LEN; + dev->tx_frame_len = IEEE802154_FCS_LEN; } size_t at86rf2xx_tx_load(at86rf2xx_t *dev, uint8_t *data, size_t len, size_t offset) { - dev->frame_len += (uint8_t)len; + dev->tx_frame_len += (uint8_t)len; at86rf2xx_sram_write(dev, offset + 1, data, len); return offset + len; } @@ -240,7 +205,7 @@ size_t at86rf2xx_tx_load(at86rf2xx_t *dev, uint8_t *data, void at86rf2xx_tx_exec(at86rf2xx_t *dev) { /* write frame length field in FIFO */ - at86rf2xx_sram_write(dev, 0, &(dev->frame_len), 1); + at86rf2xx_sram_write(dev, 0, &(dev->tx_frame_len), 1); /* trigger sending of pre-loaded frame */ at86rf2xx_reg_write(dev, AT86RF2XX_REG__TRX_STATE, AT86RF2XX_TRX_STATE__TX_START); @@ -252,6 +217,7 @@ void at86rf2xx_tx_exec(at86rf2xx_t *dev) size_t at86rf2xx_rx_len(at86rf2xx_t *dev) { uint8_t phr; + at86rf2xx_fb_read(dev, &phr, 1); /* ignore MSB (refer p.80) and substract length of FCS field */ diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index 6909a2f3da1c0..465a8c68d9403 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -16,13 +16,19 @@ * @author Thomas Eichinger * @author Hauke Petersen * @author Kévin Roussel + * @author Martine Lenders * * @} */ +#include +#include + #include "net/eui64.h" #include "net/ieee802154.h" -#include "net/gnrc.h" +#include "net/netdev2.h" +#include "net/netdev2_ieee802154.h" +#include "net/gnrc/nettype.h" #include "at86rf2xx.h" #include "at86rf2xx_netdev.h" #include "at86rf2xx_internal.h" @@ -33,323 +39,136 @@ #define _MAX_MHR_OVERHEAD (25) -/* TODO: generalize and move to (gnrc_)ieee802154 */ -static size_t _make_data_frame_hdr(at86rf2xx_t *dev, uint8_t *buf, - gnrc_netif_hdr_t *hdr) -{ - int pos = 0; +static int _send(netdev2_t *netdev, const struct iovec *vector, int count); +static int _recv(netdev2_t *netdev, char *buf, int len); +static int _init(netdev2_t *netdev); +static void _isr(netdev2_t *netdev); +static int _get(netdev2_t *netdev, netopt_t opt, void *val, size_t max_len); +static int _set(netdev2_t *netdev, netopt_t opt, void *val, size_t len); + +const netdev2_driver_t at86rf2xx_driver = { + .send = _send, + .recv = _recv, + .init = _init, + .isr = _isr, + .get = _get, + .set = _set, +}; - /* we are building a data frame here */ - buf[0] = IEEE802154_FCF_TYPE_DATA; - buf[1] = IEEE802154_FCF_VERS_V1; +static void _irq_handler(void *arg) +{ + netdev2_t *dev = (netdev2_t *) arg; - /* if AUTOACK is enabled, then we also expect ACKs for this packet */ - if (!(hdr->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST) && - !(hdr->flags & GNRC_NETIF_HDR_FLAGS_MULTICAST) && - (dev->options & AT86RF2XX_OPT_AUTOACK)) { - buf[0] |= IEEE802154_FCF_ACK_REQ; + if (dev->event_callback) { + dev->event_callback(dev, NETDEV2_EVENT_ISR, NULL); } +} - /* fill in destination PAN ID */ - pos = 3; - buf[pos++] = (uint8_t)((dev->pan) & 0xff); - buf[pos++] = (uint8_t)((dev->pan) >> 8); - - /* fill in destination address */ - if (hdr->flags & - (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { - buf[1] |= IEEE802154_FCF_DST_ADDR_SHORT; - buf[pos++] = 0xff; - buf[pos++] = 0xff; - } - else if (hdr->dst_l2addr_len == 2) { - uint8_t *dst_addr = gnrc_netif_hdr_get_dst_addr(hdr); - buf[1] |= IEEE802154_FCF_DST_ADDR_SHORT; - buf[pos++] = dst_addr[1]; - buf[pos++] = dst_addr[0]; - } - else if (hdr->dst_l2addr_len == 8) { - buf[1] |= IEEE802154_FCF_DST_ADDR_LONG; - uint8_t *dst_addr = gnrc_netif_hdr_get_dst_addr(hdr); - for (int i = 7; i >= 0; i--) { - buf[pos++] = dst_addr[i]; - } - } - else { - /* unsupported address length */ - return 0; - } +static int _init(netdev2_t *netdev) +{ + at86rf2xx_t *dev = (at86rf2xx_t *)netdev; - /* fill in source PAN ID (if applicable */ - if (dev->options & AT86RF2XX_OPT_USE_SRC_PAN) { - buf[pos++] = (uint8_t)((dev->pan) & 0xff); - buf[pos++] = (uint8_t)((dev->pan) >> 8); - } else { - buf[0] |= IEEE802154_FCF_PAN_COMP; - } + /* initialise GPIOs */ + gpio_init(dev->cs_pin, GPIO_DIR_OUT, GPIO_NOPULL); + gpio_set(dev->cs_pin); + gpio_init(dev->sleep_pin, GPIO_DIR_OUT, GPIO_NOPULL); + gpio_clear(dev->sleep_pin); + gpio_init(dev->reset_pin, GPIO_DIR_OUT, GPIO_NOPULL); + gpio_set(dev->reset_pin); + gpio_init_int(dev->int_pin, GPIO_NOPULL, GPIO_RISING, _irq_handler, dev); + dev->rx_frame_len = 0; - /* fill in source address */ - if (dev->options & AT86RF2XX_OPT_SRC_ADDR_LONG) { - buf[1] |= IEEE802154_FCF_SRC_ADDR_LONG; - memcpy(&(buf[pos]), dev->addr_long, 8); - pos += 8; - } - else { - buf[1] |= IEEE802154_FCF_SRC_ADDR_SHORT; - buf[pos++] = dev->addr_short[0]; - buf[pos++] = dev->addr_short[1]; - } + /* make sure device is not sleeping, so we can query part number */ + at86rf2xx_assert_awake(dev); - /* set sequence number */ - buf[2] = dev->seq_nr++; - /* return actual header length */ - return pos; -} + /* test if the SPI is set up correctly and the device is responding */ + if (at86rf2xx_reg_read(dev, AT86RF2XX_REG__PART_NUM) != + AT86RF2XX_PARTNUM) { + DEBUG("[at86rf2xx] error: unable to read correct part number\n"); + return -1; + } -/* TODO: generalize and move to ieee802154 */ -/* TODO: include security header implications */ -static size_t _get_frame_hdr_len(uint8_t *mhr) -{ - uint8_t tmp; - size_t len = 3; + /* reset device to default values and put it into RX state */ + at86rf2xx_reset(dev); - /* figure out address sizes */ - tmp = (mhr[1] & IEEE802154_FCF_DST_ADDR_MASK); - if (tmp == IEEE802154_FCF_DST_ADDR_SHORT) { - len += 4; - } - else if (tmp == IEEE802154_FCF_DST_ADDR_LONG) { - len += 10; - } - else if (tmp != IEEE802154_FCF_DST_ADDR_VOID) { - return 0; - } - tmp = (mhr[1] & IEEE802154_FCF_SRC_ADDR_MASK); - if (tmp == IEEE802154_FCF_SRC_ADDR_VOID) { - return len; - } - else { - if (!(mhr[0] & IEEE802154_FCF_PAN_COMP)) { - len += 2; - } - if (tmp == IEEE802154_FCF_SRC_ADDR_SHORT) { - return (len + 2); - } - else if (tmp == IEEE802154_FCF_SRC_ADDR_LONG) { - return (len + 8); - } - } return 0; } -/* TODO: generalize and move to (gnrc_)ieee802154 */ -static gnrc_pktsnip_t *_make_netif_hdr(uint8_t *mhr) -{ - uint8_t tmp; - uint8_t *addr; - uint8_t src_len, dst_len; - gnrc_pktsnip_t *snip; - gnrc_netif_hdr_t *hdr; - - /* figure out address sizes */ - tmp = mhr[1] & IEEE802154_FCF_SRC_ADDR_MASK; - if (tmp == IEEE802154_FCF_SRC_ADDR_SHORT) { - src_len = 2; - } - else if (tmp == IEEE802154_FCF_SRC_ADDR_LONG) { - src_len = 8; - } - else if (tmp == IEEE802154_FCF_SRC_ADDR_VOID) { - src_len = 0; - } - else { - return NULL; - } - tmp = mhr[1] & IEEE802154_FCF_DST_ADDR_MASK; - if (tmp == IEEE802154_FCF_DST_ADDR_SHORT) { - dst_len = 2; - } - else if (tmp == IEEE802154_FCF_DST_ADDR_LONG) { - dst_len = 8; - } - else if (tmp == IEEE802154_FCF_DST_ADDR_VOID) { - dst_len = 0; - } - else { - return NULL; - } - /* allocate space for header */ - snip = gnrc_pktbuf_add(NULL, NULL, sizeof(gnrc_netif_hdr_t) + src_len + dst_len, - GNRC_NETTYPE_NETIF); - if (snip == NULL) { - return NULL; - } - /* fill header */ - hdr = (gnrc_netif_hdr_t *)snip->data; - gnrc_netif_hdr_init(hdr, src_len, dst_len); - if (dst_len > 0) { - hdr->flags |= GNRC_NETIF_HDR_FLAGS_BROADCAST; - tmp = 5 + dst_len; - addr = gnrc_netif_hdr_get_dst_addr(hdr); - for (int i = 0; i < dst_len; i++) { - addr[i] = mhr[5 + (dst_len - i) - 1]; - if(addr[i] != 0xff) { - hdr->flags &= ~(GNRC_NETIF_HDR_FLAGS_BROADCAST); - } - } - } - else { - tmp = 3; - } - if (!(mhr[0] & IEEE802154_FCF_PAN_COMP)) { - tmp += 2; - } - if (src_len > 0) { - addr = gnrc_netif_hdr_get_src_addr(hdr); - for (int i = 0; i < src_len; i++) { - addr[i] = mhr[tmp + (src_len - i) - 1]; - } - } - return snip; -} - -static int _send(gnrc_netdev_t *netdev, gnrc_pktsnip_t *pkt) +static int _send(netdev2_t *netdev, const struct iovec *vector, int count) { at86rf2xx_t *dev = (at86rf2xx_t *)netdev; - gnrc_pktsnip_t *snip; - uint8_t mhr[IEEE802154_MAX_HDR_LEN]; - size_t len; - - if (pkt == NULL) { - return -ENOMSG; - } - if (dev == NULL) { - gnrc_pktbuf_release(pkt); - return -ENODEV; - } - - /* create 802.15.4 header */ - len = _make_data_frame_hdr(dev, mhr, (gnrc_netif_hdr_t *)pkt->data); - if (len == 0) { - DEBUG("[at86rf2xx] error: unable to create 802.15.4 header\n"); - gnrc_pktbuf_release(pkt); - return -ENOMSG; - } - /* check if packet (header + payload + FCS) fits into FIFO */ - snip = pkt->next; - if ((gnrc_pkt_len(snip) + len + 2) > AT86RF2XX_MAX_PKT_LENGTH) { - printf("[at86rf2xx] error: packet too large (%u byte) to be send\n", - gnrc_pkt_len(snip) + len + 2); - gnrc_pktbuf_release(pkt); - return -EOVERFLOW; + const struct iovec *ptr = vector; + size_t len = 0; + + assert(vector != NULL); + for (int i = 0; i < count; i++, ptr++) { + len += ptr->iov_len; + /* len + 2: packet data + FCS */ + if ((len + 2) > AT86RF2XX_MAX_PKT_LENGTH) { + printf("[at86rf2xx] error: packet too large (%u byte) to be send\n", + (unsigned)len + 2); + return -EOVERFLOW; + } } - at86rf2xx_tx_prepare(dev); - /* put header into FIFO */ - len = at86rf2xx_tx_load(dev, mhr, len, 0); + /* load packet data into FIFO */ - while (snip) { - len = at86rf2xx_tx_load(dev, snip->data, snip->size, len); - snip = snip->next; + for (int i = 0; i < count; i++, vector++) { + len = at86rf2xx_tx_load(dev, vector->iov_base, vector->iov_len, len); } + /* send data out directly if pre-loading id disabled */ if (!(dev->options & AT86RF2XX_OPT_PRELOADING)) { at86rf2xx_tx_exec(dev); } - /* release packet */ - gnrc_pktbuf_release(pkt); /* return the number of bytes that were actually send out */ return (int)len; } -static void _receive_data(at86rf2xx_t *dev) +static int _recv(netdev2_t *netdev, char *buf, int len) { - uint8_t mhr[IEEE802154_MAX_HDR_LEN]; + at86rf2xx_t *dev = (at86rf2xx_t *)netdev; uint8_t phr; - size_t pkt_len, hdr_len; - gnrc_pktsnip_t *hdr, *payload = NULL; - gnrc_netif_hdr_t *netif; + size_t pkt_len; /* frame buffer protection will be unlocked as soon as at86rf2xx_fb_stop() * is called*/ at86rf2xx_fb_start(dev); + if (dev->rx_frame_len == 0) { - /* get the size of the received packet */ - at86rf2xx_fb_read(dev, &phr, 1); + /* get the size of the received packet */ + at86rf2xx_fb_read(dev, &phr, 1); - /* Ignore FCS for packet length */ - pkt_len = phr - 2; + /* Include FCS, LQI and RSSI in packet length */ + dev->rx_frame_len = phr + 2; - /* abort here already if no event callback is registered */ - if (!dev->event_cb) { - at86rf2xx_fb_stop(dev); - return; } - - /* in raw mode, just read the binary dump into the packet buffer */ - if (dev->options & AT86RF2XX_OPT_RAWDUMP) { - payload = gnrc_pktbuf_add(NULL, NULL, pkt_len, GNRC_NETTYPE_UNDEF); - if (payload == NULL ) { - at86rf2xx_fb_stop(dev); - DEBUG("[at86rf2xx] error: unable to allocate RAW data\n"); - return; - } - at86rf2xx_fb_read(dev, payload->data, pkt_len); + /* just return length when buf == NULL */ + if (buf == NULL) { at86rf2xx_fb_stop(dev); - dev->event_cb(NETDEV_EVENT_RX_COMPLETE, payload); - return; + return dev->rx_frame_len; } - - /* get FCF field and compute 802.15.4 header length */ - at86rf2xx_fb_read(dev, mhr, 2); - - hdr_len = _get_frame_hdr_len(mhr); - if (hdr_len == 0) { + /* transfer to internal variable and reset rx_frame_len for next packet */ + pkt_len = dev->rx_frame_len; + dev->rx_frame_len = 0; + /* not enough space in buf */ + if (pkt_len > len) { at86rf2xx_fb_stop(dev); - DEBUG("[at86rf2xx] error: unable parse incoming frame header\n"); - return; - } - - /* read the rest of the header and parse the netif header from it */ - at86rf2xx_fb_read(dev, &(mhr[2]), hdr_len - 2); - hdr = _make_netif_hdr(mhr); - if (hdr == NULL) { - at86rf2xx_fb_stop(dev); - DEBUG("[at86rf2xx] error: unable to allocate netif header\n"); - return; - } - - /* fill missing fields in netif header */ - netif = (gnrc_netif_hdr_t *)hdr->data; - netif->if_pid = dev->mac_pid; - - /* allocate payload */ - payload = gnrc_pktbuf_add(hdr, NULL, (pkt_len - hdr_len), dev->proto); - if (payload == NULL) { - at86rf2xx_fb_stop(dev); - DEBUG("[at86rf2xx] error: unable to allocate incoming payload\n"); - gnrc_pktbuf_release(hdr); - return; + return -ENOBUFS; } - /* copy payload */ - at86rf2xx_fb_read(dev, payload->data, payload->size); - - /* Ignore FCS but advance fb read */ - at86rf2xx_fb_read(dev, NULL, 2); - - at86rf2xx_fb_read(dev, &(netif->lqi), 1); #ifndef MODULE_AT86RF231 - at86rf2xx_fb_read(dev, &(netif->rssi), 1); + at86rf2xx_fb_read(dev, (uint8_t *)buf, pkt_len); at86rf2xx_fb_stop(dev); #else + at86rf2xx_fb_read(dev, (uint8_t *)buf, pkt_len - 1); at86rf2xx_fb_stop(dev); - netif->rssi = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_ED_LEVEL); + /* append RSSI to packet */ + buf[pkt_len - 1] = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_ED_LEVEL); #endif - /* finish up and send data to upper layers */ - dev->event_cb(NETDEV_EVENT_RX_COMPLETE, payload); + return pkt_len; } static int _set_state(at86rf2xx_t *dev, netopt_state_t state) @@ -391,11 +210,11 @@ netopt_state_t _get_state(at86rf2xx_t *dev) } } -static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len) +static int _get(netdev2_t *netdev, netopt_t opt, void *val, size_t max_len) { - at86rf2xx_t *dev = (at86rf2xx_t *) device; + at86rf2xx_t *dev = (at86rf2xx_t *) netdev; - if (device == NULL) { + if (netdev == NULL) { return -ENODEV; } @@ -442,20 +261,6 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len) *((uint16_t *)val) = dev->pan; return sizeof(uint16_t); - case NETOPT_IPV6_IID: - if (max_len < sizeof(eui64_t)) { - return -EOVERFLOW; - } - if (dev->options & AT86RF2XX_OPT_SRC_ADDR_LONG) { - uint64_t addr = at86rf2xx_get_addr_long(dev); - ieee802154_get_iid(val, (uint8_t *)&addr, 8); - } - else { - uint16_t addr = at86rf2xx_get_addr_short(dev); - ieee802154_get_iid(val, (uint8_t *)&addr, 2); - } - return sizeof(eui64_t); - case NETOPT_PROTO: if (max_len < sizeof(gnrc_nettype_t)) { return -EOVERFLOW; @@ -490,7 +295,7 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len) if (max_len < sizeof(netopt_state_t)) { return -EOVERFLOW; } - *((netopt_state_t*)val) = _get_state(dev); + *((netopt_state_t *)val) = _get_state(dev); return sizeof(netopt_state_t); case NETOPT_PRELOADING: @@ -559,12 +364,18 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len) break; } + int res; + + if (((res = netdev2_ieee802154_get(netdev, opt, val, max_len)) >= 0) || + (res != -ENOTSUP)) { + return res; + } uint8_t old_state = at86rf2xx_get_status(dev); - int res = 0; + res = 0; /* temporarily wake up if sleeping */ - if(old_state == AT86RF2XX_STATE_SLEEP) { + if (old_state == AT86RF2XX_STATE_SLEEP) { at86rf2xx_assert_awake(dev); } @@ -573,7 +384,8 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len) case NETOPT_TX_POWER: if (max_len < sizeof(int16_t)) { res = -EOVERFLOW; - } else { + } + else { *((uint16_t *)val) = at86rf2xx_get_txpower(dev); res = sizeof(uint16_t); } @@ -582,7 +394,8 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len) case NETOPT_RETRANS: if (max_len < sizeof(uint8_t)) { res = -EOVERFLOW; - } else { + } + else { *((uint8_t *)val) = at86rf2xx_get_max_retries(dev); res = sizeof(uint8_t); } @@ -601,7 +414,8 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len) case NETOPT_CSMA_RETRIES: if (max_len < sizeof(uint8_t)) { res = -EOVERFLOW; - } else { + } + else { *((uint8_t *)val) = at86rf2xx_get_csma_max_retries(dev); res = sizeof(uint8_t); } @@ -610,7 +424,8 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len) case NETOPT_CCA_THRESHOLD: if (max_len < sizeof(int8_t)) { res = -EOVERFLOW; - } else { + } + else { *((int8_t *)val) = at86rf2xx_get_cca_threshold(dev); res = sizeof(int8_t); } @@ -621,16 +436,16 @@ static int _get(gnrc_netdev_t *device, netopt_t opt, void *val, size_t max_len) } /* go back to sleep if were sleeping */ - if(old_state == AT86RF2XX_STATE_SLEEP) { + if (old_state == AT86RF2XX_STATE_SLEEP) { at86rf2xx_set_state(dev, AT86RF2XX_STATE_SLEEP); } return res; } -static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) +static int _set(netdev2_t *netdev, netopt_t opt, void *val, size_t len) { - at86rf2xx_t *dev = (at86rf2xx_t *) device; + at86rf2xx_t *dev = (at86rf2xx_t *) netdev; uint8_t old_state = at86rf2xx_get_status(dev); int res = 0; @@ -639,7 +454,7 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) } /* temporarily wake up if sleeping */ - if(old_state == AT86RF2XX_STATE_SLEEP) { + if (old_state == AT86RF2XX_STATE_SLEEP) { at86rf2xx_assert_awake(dev); } @@ -647,8 +462,9 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_ADDRESS: if (len > sizeof(uint16_t)) { res = -EOVERFLOW; - } else { - at86rf2xx_set_addr_short(dev, *((uint16_t*)val)); + } + else { + at86rf2xx_set_addr_short(dev, *((uint16_t *)val)); res = sizeof(uint16_t); } break; @@ -656,8 +472,9 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_ADDRESS_LONG: if (len > sizeof(uint64_t)) { res = -EOVERFLOW; - } else { - at86rf2xx_set_addr_long(dev, *((uint64_t*)val)); + } + else { + at86rf2xx_set_addr_long(dev, *((uint64_t *)val)); res = sizeof(uint64_t); } break; @@ -665,7 +482,8 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_SRC_LEN: if (len > sizeof(uint16_t)) { res = -EOVERFLOW; - } else { + } + else { if (*((uint16_t *)val) == 2) { at86rf2xx_set_option(dev, AT86RF2XX_OPT_SRC_ADDR_LONG, false); @@ -685,7 +503,8 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_NID: if (len > sizeof(uint16_t)) { res = -EOVERFLOW; - } else { + } + else { at86rf2xx_set_pan(dev, *((uint16_t *)val)); res = sizeof(uint16_t); } @@ -696,7 +515,7 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) res = -EINVAL; } else { - dev->proto = *((gnrc_nettype_t*) val); + dev->proto = *((gnrc_nettype_t *) val); res = sizeof(gnrc_nettype_t); } break; @@ -704,7 +523,8 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_CHANNEL: if (len != sizeof(uint16_t)) { res = -EINVAL; - } else { + } + else { uint8_t chan = ((uint8_t *)val)[0]; if (chan < AT86RF2XX_MIN_CHANNEL || chan > AT86RF2XX_MAX_CHANNEL) { @@ -719,12 +539,14 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_CHANNEL_PAGE: if (len != sizeof(uint16_t)) { res = -EINVAL; - } else { + } + else { uint8_t page = ((uint8_t *)val)[0]; #ifdef MODULE_AT86RF212B if ((page != 0) && (page != 2)) { res = -ENOTSUP; - } else { + } + else { at86rf2xx_set_page(dev, page); res = sizeof(uint16_t); } @@ -732,7 +554,8 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) /* rf23x only supports page 0, no need to configure anything in the driver. */ if (page != 0) { res = -ENOTSUP; - } else { + } + else { res = sizeof(uint16_t); } #endif @@ -742,7 +565,8 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_TX_POWER: if (len > sizeof(int16_t)) { res = -EOVERFLOW; - } else { + } + else { at86rf2xx_set_txpower(dev, *((int16_t *)val)); res = sizeof(uint16_t); } @@ -751,7 +575,8 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_STATE: if (len > sizeof(netopt_state_t)) { res = -EOVERFLOW; - } else { + } + else { res = _set_state(dev, *((netopt_state_t *)val)); } break; @@ -765,7 +590,8 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_RETRANS: if (len > sizeof(uint8_t)) { res = -EOVERFLOW; - } else { + } + else { at86rf2xx_set_max_retries(dev, *((uint8_t *)val)); res = sizeof(uint8_t); } @@ -815,18 +641,20 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_CSMA: at86rf2xx_set_option(dev, AT86RF2XX_OPT_CSMA, - ((bool *)val)[0]); + ((bool *)val)[0]); res = sizeof(netopt_enable_t); break; case NETOPT_CSMA_RETRIES: - if( (len > sizeof(uint8_t)) || - (*((uint8_t *)val) > 5) ) { + if ((len > sizeof(uint8_t)) || + (*((uint8_t *)val) > 5)) { res = -EOVERFLOW; - } else if( !(dev->options & AT86RF2XX_OPT_CSMA) ) { + } + else if (!(dev->options & AT86RF2XX_OPT_CSMA)) { /* If CSMA is disabled, don't allow setting retries */ res = -ENOTSUP; - } else { + } + else { at86rf2xx_set_csma_max_retries(dev, *((uint8_t *)val)); res = sizeof(uint8_t); } @@ -835,7 +663,8 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) case NETOPT_CCA_THRESHOLD: if (len > sizeof(int8_t)) { res = -EOVERFLOW; - } else { + } + else { at86rf2xx_set_cca_threshold(dev, *((int8_t *)val)); res = sizeof(int8_t); } @@ -846,44 +675,21 @@ static int _set(gnrc_netdev_t *device, netopt_t opt, void *val, size_t len) } /* go back to sleep if were sleeping and state hasn't been changed */ - if( (old_state == AT86RF2XX_STATE_SLEEP) && - (opt != NETOPT_STATE) ) { + if ((old_state == AT86RF2XX_STATE_SLEEP) && + (opt != NETOPT_STATE)) { at86rf2xx_set_state(dev, AT86RF2XX_STATE_SLEEP); } - return res; -} - -static int _add_event_cb(gnrc_netdev_t *dev, gnrc_netdev_event_cb_t cb) -{ - if (dev == NULL) { - return -ENODEV; - } - if (dev->event_cb) { - return -ENOBUFS; - } - - dev->event_cb = cb; - return 0; -} - -static int _rem_event_cb(gnrc_netdev_t *dev, gnrc_netdev_event_cb_t cb) -{ - if (dev == NULL) { - return -ENODEV; - } - if (dev->event_cb != cb) { - return -ENOENT; + if (res == -ENOTSUP) { + res = netdev2_ieee802154_set(netdev, opt, val, len); } - dev->event_cb = NULL; - return 0; + return res; } -static void _isr_event(gnrc_netdev_t *device, uint32_t event_type) +static void _isr(netdev2_t *netdev) { - (void) event_type; - at86rf2xx_t *dev = (at86rf2xx_t *) device; + at86rf2xx_t *dev = (at86rf2xx_t *) netdev; uint8_t irq_mask; uint8_t state; uint8_t trac_status; @@ -892,28 +698,29 @@ static void _isr_event(gnrc_netdev_t *device, uint32_t event_type) * lost anyway, so return immediately. */ state = at86rf2xx_get_status(dev); - if(state == AT86RF2XX_STATE_SLEEP) + if (state == AT86RF2XX_STATE_SLEEP) { return; + } /* read (consume) device status */ irq_mask = at86rf2xx_reg_read(dev, AT86RF2XX_REG__IRQ_STATUS); trac_status = at86rf2xx_reg_read(dev, AT86RF2XX_REG__TRX_STATE) & - AT86RF2XX_TRX_STATE_MASK__TRAC; + AT86RF2XX_TRX_STATE_MASK__TRAC; if (irq_mask & AT86RF2XX_IRQ_STATUS_MASK__RX_START) { - dev->event_cb(NETDEV_EVENT_RX_STARTED, NULL); + dev->event_callback(netdev, NETDEV2_EVENT_RX_STARTED, NULL); DEBUG("[at86rf2xx] EVT - RX_START\n"); } if (irq_mask & AT86RF2XX_IRQ_STATUS_MASK__TRX_END) { - if(state == AT86RF2XX_STATE_RX_AACK_ON || - state == AT86RF2XX_STATE_BUSY_RX_AACK) { + if (state == AT86RF2XX_STATE_RX_AACK_ON || + state == AT86RF2XX_STATE_BUSY_RX_AACK) { DEBUG("[at86rf2xx] EVT - RX_END\n"); if (!(dev->options & AT86RF2XX_OPT_TELL_RX_END)) { return; } - _receive_data(dev); + dev->event_callback(netdev, NETDEV2_EVENT_RX_COMPLETE, NULL); } else if (state == AT86RF2XX_STATE_TX_ARET_ON || state == AT86RF2XX_STATE_BUSY_TX_ARET) { @@ -921,35 +728,26 @@ static void _isr_event(gnrc_netdev_t *device, uint32_t event_type) DEBUG("[at86rf2xx] EVT - TX_END\n"); DEBUG("[at86rf2xx] return to state 0x%x\n", dev->idle_state); - if (dev->event_cb && (dev->options & AT86RF2XX_OPT_TELL_TX_END)) { - switch(trac_status) { - case AT86RF2XX_TRX_STATE__TRAC_SUCCESS: - case AT86RF2XX_TRX_STATE__TRAC_SUCCESS_DATA_PENDING: - dev->event_cb(NETDEV_EVENT_TX_COMPLETE, NULL); - DEBUG("[at86rf2xx] TX SUCCESS\n"); - break; - case AT86RF2XX_TRX_STATE__TRAC_NO_ACK: - dev->event_cb(NETDEV_EVENT_TX_NOACK, NULL); - DEBUG("[at86rf2xx] TX NO_ACK\n"); - break; - case AT86RF2XX_TRX_STATE__TRAC_CHANNEL_ACCESS_FAILURE: - dev->event_cb(NETDEV_EVENT_TX_MEDIUM_BUSY, NULL); - DEBUG("[at86rf2xx] TX_CHANNEL_ACCESS_FAILURE\n"); - break; - default: - DEBUG("[at86rf2xx] Unhandled TRAC_STATUS: %d\n", - trac_status >> 5); + if (dev->event_callback && (dev->options & AT86RF2XX_OPT_TELL_TX_END)) { + switch (trac_status) { + case AT86RF2XX_TRX_STATE__TRAC_SUCCESS: + case AT86RF2XX_TRX_STATE__TRAC_SUCCESS_DATA_PENDING: + dev->event_callback(netdev, NETDEV2_EVENT_TX_COMPLETE, NULL); + DEBUG("[at86rf2xx] TX SUCCESS\n"); + break; + case AT86RF2XX_TRX_STATE__TRAC_NO_ACK: + dev->event_callback(netdev, NETDEV2_EVENT_TX_NOACK, NULL); + DEBUG("[at86rf2xx] TX NO_ACK\n"); + break; + case AT86RF2XX_TRX_STATE__TRAC_CHANNEL_ACCESS_FAILURE: + dev->event_callback(netdev, NETDEV2_EVENT_TX_MEDIUM_BUSY, NULL); + DEBUG("[at86rf2xx] TX_CHANNEL_ACCESS_FAILURE\n"); + break; + default: + DEBUG("[at86rf2xx] Unhandled TRAC_STATUS: %d\n", + trac_status >> 5); } } } } } - -const gnrc_netdev_driver_t at86rf2xx_driver = { - .send_data = _send, - .add_event_callback = _add_event_cb, - .rem_event_callback = _rem_event_cb, - .get = _get, - .set = _set, - .isr_event = _isr_event, -}; diff --git a/drivers/at86rf2xx/include/at86rf2xx_netdev.h b/drivers/at86rf2xx/include/at86rf2xx_netdev.h index 92a1fdc9953b3..7b6e1f18a38af 100644 --- a/drivers/at86rf2xx/include/at86rf2xx_netdev.h +++ b/drivers/at86rf2xx/include/at86rf2xx_netdev.h @@ -19,7 +19,7 @@ #ifndef AT86RF2XX_NETDEV_H_ #define AT86RF2XX_NETDEV_H_ -#include "net/gnrc/netdev.h" +#include "net/netdev2.h" #ifdef __cplusplus extern "C" { @@ -28,7 +28,7 @@ extern "C" { /** * @brief Reference to the netdev device driver struct */ -extern const gnrc_netdev_driver_t at86rf2xx_driver; +extern const netdev2_driver_t at86rf2xx_driver; #ifdef __cplusplus } diff --git a/drivers/include/at86rf2xx.h b/drivers/include/at86rf2xx.h index adf2f4da854fd..35421752cc4fe 100644 --- a/drivers/include/at86rf2xx.h +++ b/drivers/include/at86rf2xx.h @@ -8,7 +8,7 @@ /** * @defgroup drivers_at86rf2xx AT86RF2xx based drivers - * @ingroup drivers_netdev + * @ingroup drivers_netdev2 * * This module contains drivers for radio devices in Atmel's AT86RF2xx series. * The driver is aimed to work with all devices of this series. @@ -34,7 +34,7 @@ #include "board.h" #include "periph/spi.h" #include "periph/gpio.h" -#include "net/gnrc/netdev.h" +#include "net/netdev2.h" #ifdef __cplusplus extern "C" { @@ -54,9 +54,9 @@ extern "C" { /** @} */ /** - * @brief Channel configuration - * @{ - */ + * @brief Channel configuration + * @{ + */ #ifdef MODULE_AT86RF212B /* the AT86RF212B has a sub-1GHz radio */ #define AT86RF2XX_MIN_CHANNEL (0) @@ -129,22 +129,23 @@ extern "C" { * @brief Device descriptor for AT86RF2XX radio devices */ typedef struct { - /* netdev fields */ - const gnrc_netdev_driver_t *driver; /**< pointer to the devices interface */ - gnrc_netdev_event_cb_t event_cb; /**< netdev event callback */ - kernel_pid_t mac_pid; /**< the driver's thread's PID */ + /* netdev2 fields */ + const struct netdev2_driver *driver; /**< ptr to that driver's interface. */ + netdev2_event_cb_t event_callback; /**< callback for device events */ + void *isr_arg; /**< argument to pass on isr event */ /* device specific fields */ - spi_t spi; /**< used SPI device */ - gpio_t cs_pin; /**< chip select pin */ - gpio_t sleep_pin; /**< sleep pin */ - gpio_t reset_pin; /**< reset pin */ - gpio_t int_pin; /**< external interrupt pin */ - gnrc_nettype_t proto; /**< protocol the radio expects */ - uint8_t state; /**< current state of the radio */ - uint8_t seq_nr; /**< sequence number to use next */ - uint8_t frame_len; /**< length of the current TX frame */ - uint16_t pan; /**< currently used PAN ID */ - uint8_t chan; /**< currently used channel number */ + spi_t spi; /**< used SPI device */ + gpio_t cs_pin; /**< chip select pin */ + gpio_t sleep_pin; /**< sleep pin */ + gpio_t reset_pin; /**< reset pin */ + gpio_t int_pin; /**< external interrupt pin */ + gnrc_nettype_t proto; /**< protocol the radio expects */ + uint8_t state; /**< current state of the radio */ + uint8_t seq_nr; /**< sequence number to use next */ + uint8_t rx_frame_len; /**< length of the current RX frame */ + uint8_t tx_frame_len; /**< length of the current TX frame */ + uint16_t pan; /**< currently used PAN ID */ + uint8_t chan; /**< currently used channel number */ #ifdef MODULE_AT86RF212B /* Only AT86RF212B supports multiple pages (PHY modes) */ uint8_t page; /**< currently used channel page */ @@ -168,7 +169,7 @@ typedef struct at86rf2xx_params { } at86rf2xx_params_t; /** - * @brief Initialize a given AT86RF2xx device + * @brief Setup an AT86RF2xx based device state * * @param[out] dev device descriptor * @param[in] spi SPI bus the device is connected to @@ -177,13 +178,10 @@ typedef struct at86rf2xx_params { * @param[in] int_pin GPIO pin connected to the interrupt pin * @param[in] sleep_pin GPIO pin connected to the sleep pin * @param[in] reset_pin GPIO pin connected to the reset pin - * - * @return 0 on success - * @return <0 on error */ -int at86rf2xx_init(at86rf2xx_t *dev, spi_t spi, spi_speed_t spi_speed, - gpio_t cs_pin, gpio_t int_pin, - gpio_t sleep_pin, gpio_t reset_pin); +void at86rf2xx_setup(at86rf2xx_t *dev, spi_t spi, spi_speed_t spi_speed, + gpio_t cs_pin, gpio_t int_pin, gpio_t sleep_pin, + gpio_t reset_pin); /** * @brief Trigger a hardware reset and configure radio with default values diff --git a/drivers/include/net/netdev2.h b/drivers/include/net/netdev2.h index d6904a3dcac15..33a920d2b207a 100644 --- a/drivers/include/net/netdev2.h +++ b/drivers/include/net/netdev2.h @@ -52,7 +52,7 @@ enum { NETDEV2_TYPE_UNKNOWN, NETDEV2_TYPE_RAW, NETDEV2_TYPE_ETHERNET, - NETDEV2_TYPE_802154, + NETDEV2_TYPE_IEEE802154, NETDEV2_TYPE_CC110X, }; @@ -61,13 +61,15 @@ enum { * upper layer */ typedef enum { - NETDEV2_EVENT_ISR, /**< driver needs it's ISR handled */ - NETDEV2_EVENT_RX_STARTED, /**< started to receive a packet */ - NETDEV2_EVENT_RX_COMPLETE, /**< finished receiving a packet */ - NETDEV2_EVENT_TX_STARTED, /**< started to transfer a packet */ - NETDEV2_EVENT_TX_COMPLETE, /**< finished transferring packet */ - NETDEV2_EVENT_LINK_UP, /**< link established */ - NETDEV2_EVENT_LINK_DOWN, /**< link gone */ + NETDEV2_EVENT_ISR, /**< driver needs it's ISR handled */ + NETDEV2_EVENT_RX_STARTED, /**< started to receive a packet */ + NETDEV2_EVENT_RX_COMPLETE, /**< finished receiving a packet */ + NETDEV2_EVENT_TX_STARTED, /**< started to transfer a packet */ + NETDEV2_EVENT_TX_COMPLETE, /**< finished transferring packet */ + NETDEV2_EVENT_TX_NOACK, /**< ACK requested but not received */ + NETDEV2_EVENT_TX_MEDIUM_BUSY, /**< couldn't transfer packet */ + NETDEV2_EVENT_LINK_UP, /**< link established */ + NETDEV2_EVENT_LINK_DOWN, /**< link gone */ /* expand this list if needed */ } netdev2_event_t; @@ -82,7 +84,7 @@ typedef struct netdev2 netdev2_t; * @param[in] type type of the event * @param[in] arg event argument */ -typedef void (*netdev2_event_cb_t)(netdev2_t *dev, netdev2_event_t event, void* arg); +typedef void (*netdev2_event_cb_t)(netdev2_t *dev, netdev2_event_t event, void *arg); /** * @brief Structure to hold driver state @@ -93,7 +95,7 @@ typedef void (*netdev2_event_cb_t)(netdev2_t *dev, netdev2_event_t event, void* struct netdev2 { const struct netdev2_driver *driver; /**< ptr to that driver's interface. */ netdev2_event_cb_t event_callback; /**< callback for device events */ - void* isr_arg; /**< argument to pass on isr event */ + void *isr_arg; /**< argument to pass on isr event */ }; /** @@ -127,7 +129,7 @@ typedef struct netdev2_driver { * @return nr of bytes read if buf != NULL * @return packet size if buf == NULL */ - int (*recv)(netdev2_t *dev, char* buf, int len); + int (*recv)(netdev2_t *dev, char *buf, int len); /** * @brief the driver's initialization function diff --git a/drivers/netdev2_ieee802154/netdev2_ieee802154.c b/drivers/netdev2_ieee802154/netdev2_ieee802154.c index d63db5367d2c3..ba31ede6fd016 100644 --- a/drivers/netdev2_ieee802154/netdev2_ieee802154.c +++ b/drivers/netdev2_ieee802154/netdev2_ieee802154.c @@ -57,21 +57,21 @@ int netdev2_eth_get(netdev2_t *dev, netopt_t opt, void *value, size_t max_len) switch (opt) { case NETOPT_DEVICE_TYPE: - { - uint16_t *tgt = (uint16_t *)value; - *tgt = NETDEV2_TYPE_IEEE802154; - res = 2; - break; - } + { + uint16_t *tgt = (uint16_t *)value; + *tgt = NETDEV2_TYPE_IEEE802154; + res = 2; + break; + } case NETOPT_IPV6_IID: - { - return _get_iid(dev, value, max_len); - } + { + return _get_iid(dev, value, max_len); + } default: - { - res = -ENOTSUP; - break; - } + { + res = -ENOTSUP; + break; + } } return res; diff --git a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_ieee802154.c b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_ieee802154.c index 0870dab1c2aa4..a88a30e9a1847 100644 --- a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_ieee802154.c +++ b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_ieee802154.c @@ -108,7 +108,7 @@ static gnrc_pktsnip_t *_recv(gnrc_netdev2_t *gnrc_netdev2) return NULL; } if ((dev->driver->get(dev, NETOPT_RAWMODE, &raw, sizeof(raw)) <= 0) || - (raw != NETOPT_ENABLE)) { + (raw != NETOPT_ENABLE)) { gnrc_pktsnip_t *ieee802154_hdr, *netif_hdr; gnrc_netif_hdr_t *hdr; uint8_t *data;