Blame view

RIOT/drivers/kw2xrf/kw2xrf.c 3.6 KB
a752c7ab   elopes   add first test an...
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);
  }