You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.6 KiB
132 lines
3.6 KiB
/* |
|
* Copyright (C) 2016 PHYTEC Messtechnik GmbH |
|
* |
|
* 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_kw2xrf |
|
* @{ |
|
* @file |
|
* @brief Basic functionality of kw2xrf driver |
|
* |
|
* @author Johann Fischer <j.fischer@phytec.de> |
|
* @author Jonas Remmert <j.remmert@phytec.de> |
|
* @author Oliver Hahm <oliver.hahm@inria.fr> |
|
* @author Sebastian Meiling <s@mlng.net> |
|
* @} |
|
*/ |
|
#include <stdint.h> |
|
#include <string.h> |
|
|
|
#include "log.h" |
|
#include "mutex.h" |
|
#include "msg.h" |
|
#include "periph/gpio.h" |
|
#include "periph/cpuid.h" |
|
#include "net/gnrc.h" |
|
#include "net/ieee802154.h" |
|
#include "luid.h" |
|
|
|
#include "kw2xrf.h" |
|
#include "kw2xrf_spi.h" |
|
#include "kw2xrf_reg.h" |
|
#include "kw2xrf_netdev.h" |
|
#include "kw2xrf_getset.h" |
|
#include "kw2xrf_intern.h" |
|
|
|
#define ENABLE_DEBUG (0) |
|
#include "debug.h" |
|
|
|
static void kw2xrf_set_address(kw2xrf_t *dev) |
|
{ |
|
DEBUG("[kw2xrf] set MAC addresses\n"); |
|
eui64_t addr_long; |
|
/* get an 8-byte unique ID to use as hardware address */ |
|
luid_get(addr_long.uint8, IEEE802154_LONG_ADDRESS_LEN); |
|
/* make sure we mark the address as non-multicast and not globally unique */ |
|
addr_long.uint8[0] &= ~(0x01); |
|
addr_long.uint8[0] |= (0x02); |
|
/* set short and long address */ |
|
kw2xrf_set_addr_long(dev, ntohll(addr_long.uint64.u64)); |
|
kw2xrf_set_addr_short(dev, ntohs(addr_long.uint16[0].u16)); |
|
} |
|
|
|
void kw2xrf_setup(kw2xrf_t *dev, const kw2xrf_params_t *params) |
|
{ |
|
netdev_t *netdev = (netdev_t *)dev; |
|
|
|
netdev->driver = &kw2xrf_driver; |
|
/* initialize device descriptor */ |
|
memcpy(&dev->params, params, sizeof(kw2xrf_params_t)); |
|
dev->idle_state = XCVSEQ_RECEIVE; |
|
dev->state = 0; |
|
dev->pending_tx = 0; |
|
kw2xrf_spi_init(dev); |
|
kw2xrf_set_power_mode(dev, KW2XRF_IDLE); |
|
DEBUG("[kw2xrf] setup finished\n"); |
|
} |
|
|
|
int kw2xrf_init(kw2xrf_t *dev, gpio_cb_t cb) |
|
{ |
|
if (dev == NULL) { |
|
return -ENODEV; |
|
} |
|
|
|
kw2xrf_set_out_clk(dev); |
|
kw2xrf_disable_interrupts(dev); |
|
/* set up GPIO-pin used for IRQ */ |
|
gpio_init_int(dev->params.int_pin, GPIO_IN, GPIO_FALLING, cb, dev); |
|
|
|
kw2xrf_abort_sequence(dev); |
|
kw2xrf_update_overwrites(dev); |
|
kw2xrf_timer_init(dev, KW2XRF_TIMEBASE_62500HZ); |
|
DEBUG("[kw2xrf] init finished\n"); |
|
|
|
return 0; |
|
} |
|
|
|
void kw2xrf_reset_phy(kw2xrf_t *dev) |
|
{ |
|
/* reset options and sequence number */ |
|
dev->netdev.seq = 0; |
|
dev->netdev.flags = 0; |
|
|
|
/* set default protocol */ |
|
#ifdef MODULE_GNRC_SIXLOWPAN |
|
dev->netdev.proto = GNRC_NETTYPE_SIXLOWPAN; |
|
#elif MODULE_GNRC |
|
dev->netdev.proto = GNRC_NETTYPE_UNDEF; |
|
#endif |
|
|
|
dev->tx_power = KW2XRF_DEFAULT_TX_POWER; |
|
kw2xrf_set_tx_power(dev, dev->tx_power); |
|
|
|
kw2xrf_set_channel(dev, KW2XRF_DEFAULT_CHANNEL); |
|
|
|
kw2xrf_set_pan(dev, KW2XRF_DEFAULT_PANID); |
|
kw2xrf_set_address(dev); |
|
|
|
kw2xrf_set_cca_mode(dev, 1); |
|
|
|
kw2xrf_set_rx_watermark(dev, 1); |
|
|
|
kw2xrf_set_option(dev, KW2XRF_OPT_AUTOACK, true); |
|
kw2xrf_set_option(dev, KW2XRF_OPT_ACK_REQ, true); |
|
kw2xrf_set_option(dev, KW2XRF_OPT_AUTOCCA, true); |
|
|
|
kw2xrf_set_power_mode(dev, KW2XRF_AUTODOZE); |
|
kw2xrf_set_sequence(dev, dev->idle_state); |
|
|
|
kw2xrf_set_option(dev, KW2XRF_OPT_TELL_RX_START, true); |
|
kw2xrf_set_option(dev, KW2XRF_OPT_TELL_RX_END, true); |
|
kw2xrf_set_option(dev, KW2XRF_OPT_TELL_TX_END, true); |
|
kw2xrf_clear_dreg_bit(dev, MKW2XDM_PHY_CTRL2, MKW2XDM_PHY_CTRL2_SEQMSK); |
|
|
|
kw2xrf_enable_irq_b(dev); |
|
|
|
DEBUG("[kw2xrf] init phy and (re)set to channel %d and pan %d.\n", |
|
KW2XRF_DEFAULT_CHANNEL, KW2XRF_DEFAULT_PANID); |
|
}
|
|
|