kw2xrf.c
3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* 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);
}