nrfmin.h
6.53 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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/*
* Copyright (C) 2015-2017 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_nrf5x_nrfmin NRF minimal radio driver
* @ingroup drivers_netdev
* @brief Minimal driver for the NRF51 radio
*
* This driver uses the nRF5x radio in a proprietary/custom way, defining our
* own custom link layer. This custom link layer resembles some characteristics
* of the IEEE802.15.4 link layer, but is not at all compatible to it.
*
* One key point is, that this custom link layer is only meant to operate
* between nRF5x devices, which let's us make some very nice assumptions:
* - all communicating hosts are little-endian
* -> we define host byte order := network byte order
*
* The driver is using a Nordic proprietary physical layer, configured to a
* bitrate of 2Mbit. The maximum payload length can be freely configured, but
* the maximal supported value is 250 byte (default is 200 byte).
*
* We define the nrfmin link layer to use 16-bit addresses. On the physical
* layer we encode these addresses by putting these addresses into the 2 least
* significant bytes of the supported 5-byte addresses, while setting the other
* 3 bytes to 0xe7.
*
* For out custom link layer, we define our own proprietary link layer format
* (all fields are in host byte order (little endian)):
*
* byte0 | byte1 - byte2 | byte3 - byte4 | byte5 | byte7 - byteN
* ------ | ------------- | ------------- | ----- | -------------
* length | src_addr | dst_addr | proto | payload...
*
* With:
* - length: length of the packet, including the header -> payload len + 6
* - src_addr: 16-bit source address
* - dst_addr: 16-bit destination address
* - proto: type of data transferred (similar to an Ethertype field)
*
* SUMMARY:
* This driver / link layer supports:
* - 16-bit addressing (16-bit)
* -> extract default address from CPU ID
* - broadcast (broadcast address is ff:ff)
* - channels from 0 to 31 [2400MHz to 2524MHz, 4MHz per channel]
* - setting of TX power [+4dBm to -20dBm, in ~4dBm steps]
* - 8-bit packet type/proto field (to be used as seen fit)
* - setting device state (RX, SLEEP)
*
* But so far no support for:
* - link layer ACKs
* - retransmissions
*
* @todo So far the driver uses only a single RX buffer that is locked
* until the data was read/discarded. This can potentially lead to
* a lot of packet loss -> using more than one buffer would help
* here...
*
* @{
*
* @file
* @brief Interface definition for the nrfmin NRF51822 radio driver
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef NRFMIN_H
#define NRFMIN_H
#include "net/netdev.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief nrfmin channel configuration
* @{
*/
#define NRFMIN_CHAN_MIN (0U)
#define NRFMIN_CHAN_DEFAULT (0U) /* 2400MHz */
#define NRFMIN_CHAN_MAX (32)
/** @} */
/**
* @brief Default transmission power used
*/
#define NRFMIN_TXPOWER_DEFAULT (0) /* 0dBm */
/**
* @brief Export the default nrfmin broadcast address
*/
#define NRFMIN_ADDR_BCAST (0xffff)
/**
* @brief Default maximum payload length (must be <= 250)
*/
#ifndef NRFMIN_PAYLOAD_MAX
#define NRFMIN_PAYLOAD_MAX (200U)
#endif
/**
* @brief Export some information on header and packet lengths
* @{
*/
#define NRFMIN_HDR_LEN (sizeof(nrfmin_hdr_t))
#define NRFMIN_PKT_MAX (NRFMIN_HDR_LEN + NRFMIN_PAYLOAD_MAX)
/** @} */
/**
* @brief Header format used for our custom nrfmin link layer
*/
typedef struct __attribute__((packed)) {
uint8_t len; /**< packet length, including this header */
uint16_t src_addr; /**< source address of the packet */
uint16_t dst_addr; /**< destination address */
uint8_t proto; /**< protocol of payload */
} nrfmin_hdr_t;
/**
* @brief In-memory structure of a nrfmin radio packet
*/
typedef union {
struct __attribute__((packed)) {
nrfmin_hdr_t hdr; /**< the nrfmin header */
uint8_t payload[NRFMIN_PAYLOAD_MAX]; /**< actual payload */
} pkt; /**< typed packet access */
uint8_t raw[NRFMIN_PKT_MAX]; /**< raw packet access */
} nrfmin_pkt_t;
/**
* @brief Export the netdev device descriptor
*/
extern netdev_t nrfmin_dev;
/**
* @brief Reference to the netdev driver interface
*/
extern const netdev_driver_t nrfmin_netdev;
/**
* @brief Setup the device driver's data structures
*/
void nrfmin_setup(void);
/**
* @brief Get the currently active address
* @return the 16-bit node address
*/
uint16_t nrfmin_get_addr(void);
/**
* @brief Set the 16-bit radio address
*
* @param[in] addr address to set
*/
void nrfmin_set_addr(uint16_t addr);
/**
* @brief Get a pseudo 64-bit long address (needed by IPv6 and 6LoWPAN)
*
* As we do not support 64-bit addresses, we just make one up, for this we
* simply return 4 times concatenated the 16-bit address.
*
* @param[out] addr 64-bit pseudo long address, as array of 4 * 16-bit
*/
void nrfmin_get_pseudo_long_addr(uint16_t *addr);
/**
* @brief Get the IID build from the 16-bit node address
*
* @param[out] iid the 64-bit IID, as array of 4 * 16-bit
*/
void nrfmin_get_iid(uint16_t *iid);
/**
* @brief Get the current channel
*
* @return currently active channel
*/
uint16_t nrfmin_get_channel(void);
/**
* @brief Set the active channel
*
* @param[in] chan targeted channel [0-31]
*
* @return sizeof(uint16_t) on success
* @return -EOVERFLOW if channel is not applicable
*/
int nrfmin_set_channel(uint16_t chan);
/**
* @brief Get the current radio state
*
* @return state the radio is currently in
*/
netopt_state_t nrfmin_get_state(void);
/**
* @brief Put the device into the given state
*
* @param[in] val target state
*
* @return sizeof(netopt_state_t) on success
* @return -ENOTSUP if target state is not applicable
*/
int nrfmin_set_state(netopt_state_t val);
/**
* @brief Get the current transmit power
*
* @return transmission power in [dBm]
*/
int16_t nrfmin_get_txpower(void);
/**
* @brief Set the used transmission power
*
* @param[in] power targeted power, in [dBm]
*/
void nrfmin_set_txpower(int16_t power);
#ifdef __cplusplus
}
#endif
#endif /* NRFMIN_H */
/** @} */