Arduino LMIC 6.0.1
Arduino LoRaWAN(r) MAC in C
Loading...
Searching...
No Matches
lorabase.h
1/*
2 * Copyright (c) 2014-2016 IBM Corporation.
3 * Copyright (c) 2017-2021 MCCI Corporation.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the <organization> nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef _lorabase_h_
30#define _lorabase_h_
31
32#ifdef __cplusplus
33extern "C"{
34#endif
35
36// ================================================================================
37// BEG: Keep in sync with lorabase.hpp
38//
39
40enum _cr_t { CR_4_5=0, CR_4_6, CR_4_7, CR_4_8 };
41enum _sf_t { FSK=0, SF7, SF8, SF9, SF10, SF11, SF12, SFrfu };
42enum _bw_t { BW125=0, BW250, BW500, BWrfu };
43typedef u1_t cr_t;
44typedef u1_t sf_t;
45typedef u1_t bw_t;
46typedef u1_t dr_t;
47typedef u2_t rxsyms_t;
48
49// Radio parameter set (encodes SF/BW/CR/IH/NOCRC)
50// 2..0: Spreading factor
51// 4..3: bandwidth: 0 == 125kHz, 1 == 250 kHz, 2 == 500 kHz. 3 == reserved.
52// 6..5: coding rate: 0 == 4/5, 1 == 4/6, 2 == 4/7, 3 == 4/8
53// 7: nocrc: 0 == with crc, 1 == without crc
54// 15..8: Implicit header control: 0 ==> none, 1..0xFF ==> length in bytes.
55
56typedef u2_t rps_t;
57TYPEDEF_xref2rps_t;
58
59enum { ILLEGAL_RPS = 0xFF };
60
61// Global maximum frame length
62enum { STD_PREAMBLE_LEN = 8 };
63enum { MAX_LEN_FRAME = LMIC_MAX_FRAME_LENGTH };
64enum { LEN_DEVNONCE = 2 };
65enum { LEN_ARTNONCE = 3 };
66enum { LEN_NETID = 3 };
67enum { DELAY_JACC1 = 5 }; // in secs
68enum { DELAY_DNW1 = 1 }; // in secs down window #1
69enum { DELAY_EXTDNW2 = 1 }; // in secs
70enum { DELAY_JACC2 = DELAY_JACC1+(int)DELAY_EXTDNW2 }; // in secs
71enum { DELAY_DNW2 = DELAY_DNW1 +(int)DELAY_EXTDNW2 }; // in secs down window #1
72enum { BCN_INTV_exp = 7 };
73enum { BCN_INTV_sec = 1<<BCN_INTV_exp };
74enum { BCN_INTV_ms = BCN_INTV_sec*1000L };
75enum { BCN_INTV_us = BCN_INTV_ms*1000L };
76enum { BCN_RESERVE_ms = 2120 }; // space reserved for beacon and NWK management
77enum { BCN_GUARD_ms = 3000 }; // end of beacon period to prevent interference with beacon
78enum { BCN_SLOT_SPAN_ms = 30 }; // 2^12 reception slots a this span
79enum { BCN_WINDOW_ms = BCN_INTV_ms-(int)BCN_GUARD_ms-(int)BCN_RESERVE_ms };
80enum { BCN_RESERVE_us = 2120000 };
81enum { BCN_GUARD_us = 3000000 };
82enum { BCN_SLOT_SPAN_us = 30000 };
83
84// there are exactly 16 datarates
85enum _dr_code_t {
86 LORAWAN_DR0 = 0,
87 LORAWAN_DR1,
88 LORAWAN_DR2,
89 LORAWAN_DR3,
90 LORAWAN_DR4,
91 LORAWAN_DR5,
92 LORAWAN_DR6,
93 LORAWAN_DR7,
94 LORAWAN_DR8,
95 LORAWAN_DR9,
96 LORAWAN_DR10,
97 LORAWAN_DR11,
98 LORAWAN_DR12,
99 LORAWAN_DR13,
100 LORAWAN_DR14,
101 LORAWAN_DR15,
102 LORAWAN_DR_LENGTH // 16, for sizing arrays.
103};
104
105// post conditions from this block: symbols used by general code that is not
106// ostensiblly region-specific.
107// DR_DFLTMIN must be defined as a suitable substititute value if we get a bogus DR
108// It is misnamed, it should be the maximum DR (which is the minimum SF) for
109// 125 kHz.
110// DR_PAGE is used only for a non-supported debug system, but should be defined.
111// CHNL_DNW2 is the channel to be used for RX2
112// FREQ_DNW2 is the frequency to be used for RX2
113// DR_DNW2 is the data-rate to be used for RX2
114//
115// The Class B stuff is untested and definitely wrong in parts for LoRaWAN 1.02
116// CHNL_PING is the channel to be used for pinging.
117// FREQ_PING is the default ping channel frequency
118// DR_PING is the data-rate to be used for pings.
119// CHNL_BCN is the channel to be used for the beacon (or perhaps the start chan)
120// FREQ_BCN is the frequency to be used for the beacon
121// DR_BCN is the datarate to be used for the beacon
122// AIRTIME_BCN is the airtime for the beacon
123
124
125
126#if defined(CFG_eu868) // ==============================================
127
128#include "lorabase_eu868.h"
129
130// per 2.1.3: not implemented
131#define LMIC_ENABLE_TxParamSetupReq 0
132
133enum { DR_DFLTMIN = EU868_DR_SF7 }; // DR5
134 // DR_PAGE is a debugging parameter
135enum { DR_PAGE = DR_PAGE_EU868 };
136
137//enum { CHNL_PING = 5 };
138enum { FREQ_PING = EU868_F6 }; // default ping freq
139enum { DR_PING = EU868_DR_SF9 }; // default ping DR
140 //enum { CHNL_DNW2 = 5 };
141enum { FREQ_DNW2 = EU868_F6 };
142enum { DR_DNW2 = EU868_DR_SF12 };
143enum { CHNL_BCN = 5 };
144enum { FREQ_BCN = EU868_F6 };
145enum { DR_BCN = EU868_DR_SF9 };
146enum { AIRTIME_BCN = 144384 }; // micros
147enum { LMIC_REGION_EIRP = EU868_LMIC_REGION_EIRP }; // region uses EIRP
148
149enum {
150 // Beacon frame format EU SF9
151 OFF_BCN_NETID = 0,
152 OFF_BCN_TIME = 3,
153 OFF_BCN_CRC1 = 7,
154 OFF_BCN_INFO = 8,
155 OFF_BCN_LAT = 9,
156 OFF_BCN_LON = 12,
157 OFF_BCN_CRC2 = 15,
158 LEN_BCN = 17
159};
160
161// for backwards compatibility. This must match _dr_eu868_t
162# if LMIC_DR_LEGACY
163enum _dr_configured_t {
164 DR_SF12 = EU868_DR_SF12,
165 DR_SF11 = EU868_DR_SF11,
166 DR_SF10 = EU868_DR_SF10,
167 DR_SF9 = EU868_DR_SF9,
168 DR_SF8 = EU868_DR_SF8,
169 DR_SF7 = EU868_DR_SF7,
170 DR_SF7B = EU868_DR_SF7B,
171 DR_FSK = EU868_DR_FSK,
172 DR_NONE = EU868_DR_NONE
173};
174# endif // LMIC_DR_LEGACY
175
176#elif defined(CFG_us915) // =========================================
177
178#include "lorabase_us915.h"
179
180// per 2.2.3: not implemented
181#define LMIC_ENABLE_TxParamSetupReq 0
182
183enum { DR_DFLTMIN = US915_DR_SF7 }; // DR5
184
185// DR_PAGE is a debugging parameter; it must be defined but it has no use in arduino-lmic
186enum { DR_PAGE = DR_PAGE_US915 };
187
188//enum { CHNL_PING = 0 }; // used only for default init of state (follows beacon - rotating)
189enum { FREQ_PING = US915_500kHz_DNFBASE + 0*US915_500kHz_DNFSTEP }; // default ping freq
190enum { DR_PING = US915_DR_SF10CR }; // default ping DR
191//enum { CHNL_DNW2 = 0 };
192enum { FREQ_DNW2 = US915_500kHz_DNFBASE + 0*US915_500kHz_DNFSTEP };
193enum { DR_DNW2 = US915_DR_SF12CR };
194enum { CHNL_BCN = 0 }; // used only for default init of state (rotating beacon scheme)
195enum { DR_BCN = US915_DR_SF12CR };
196// TODO(tmm@mcci.com): check this, as beacon DR was SF10 in IBM code.
197enum { AIRTIME_BCN = 72192 }; // micros
198enum { LMIC_REGION_EIRP = US915_LMIC_REGION_EIRP }; // region uses EIRP
199
200enum {
201 // Beacon frame format US SF10
202 OFF_BCN_NETID = 0,
203 OFF_BCN_TIME = 3,
204 OFF_BCN_CRC1 = 7,
205 OFF_BCN_INFO = 9,
206 OFF_BCN_LAT = 10,
207 OFF_BCN_LON = 13,
208 OFF_BCN_RFU1 = 16,
209 OFF_BCN_CRC2 = 17,
210 LEN_BCN = 19
211};
212
213# if LMIC_DR_LEGACY
214enum _dr_configured_t {
215 DR_SF10 = US915_DR_SF10,
216 DR_SF9 = US915_DR_SF9,
217 DR_SF8 = US915_DR_SF8,
218 DR_SF7 = US915_DR_SF7,
219 DR_SF8C = US915_DR_SF8C,
220 DR_NONE = US915_DR_NONE,
221 DR_SF12CR = US915_DR_SF12CR,
222 DR_SF11CR = US915_DR_SF11CR,
223 DR_SF10CR = US915_DR_SF10CR,
224 DR_SF9CR = US915_DR_SF9CR,
225 DR_SF8CR = US915_DR_SF8CR,
226 DR_SF7CR = US915_DR_SF7CR
227};
228# endif // LMIC_DR_LEGACY
229
230#elif defined(CFG_au915) // =========================================
231
232#include "lorabase_au915.h"
233
234// per 2.5.3: must be implemented
235#define LMIC_ENABLE_TxParamSetupReq 1
236
237enum { DR_DFLTMIN = AU915_DR_SF7 }; // DR5
238
239 // DR_PAGE is a debugging parameter; it must be defined but it has no use in arduino-lmic
240enum { DR_PAGE = DR_PAGE_AU915 };
241
242//enum { CHNL_PING = 0 }; // used only for default init of state (follows beacon - rotating)
243enum { FREQ_PING = AU915_500kHz_DNFBASE + 0*AU915_500kHz_DNFSTEP }; // default ping freq
244enum { DR_PING = AU915_DR_SF10CR }; // default ping DR
245//enum { CHNL_DNW2 = 0 };
246enum { FREQ_DNW2 = AU915_500kHz_DNFBASE + 0*AU915_500kHz_DNFSTEP };
247enum { DR_DNW2 = AU915_DR_SF12CR }; // DR8
248enum { CHNL_BCN = 0 }; // used only for default init of state (rotating beacon scheme)
249enum { DR_BCN = AU915_DR_SF10CR };
250enum { AIRTIME_BCN = 72192 }; // micros ... TODO(tmm@mcci.com) check.
251enum { LMIC_REGION_EIRP = AU915_LMIC_REGION_EIRP }; // region uses EIRP
252
253enum {
254 // Beacon frame format AU DR10/SF10 500kHz
255 OFF_BCN_NETID = 0,
256 OFF_BCN_TIME = 3,
257 OFF_BCN_CRC1 = 7,
258 OFF_BCN_INFO = 9,
259 OFF_BCN_LAT = 10,
260 OFF_BCN_LON = 13,
261 OFF_BCN_RFU1 = 16,
262 OFF_BCN_CRC2 = 17,
263 LEN_BCN = 19
264};
265
266# if LMIC_DR_LEGACY
267enum _dr_configured_t {
268 DR_SF12 = AU915_DR_SF12,
269 DR_SF11 = AU915_DR_SF11,
270 DR_SF10 = AU915_DR_SF10,
271 DR_SF9 = AU915_DR_SF9,
272 DR_SF8 = AU915_DR_SF8,
273 DR_SF7 = AU915_DR_SF7,
274 DR_SF8C = AU915_DR_SF8C,
275 DR_NONE = AU915_DR_NONE,
276 DR_SF12CR = AU915_DR_SF12CR,
277 DR_SF11CR = AU915_DR_SF11CR,
278 DR_SF10CR = AU915_DR_SF10CR,
279 DR_SF9CR = AU915_DR_SF9CR,
280 DR_SF8CR = AU915_DR_SF8CR,
281 DR_SF7CR = AU915_DR_SF7CR
282};
283# endif // LMIC_DR_LEGACY
284
285#elif defined(CFG_as923) // ==============================================
286
287#include "lorabase_as923.h"
288
289// per 2.7.3: must be implemented
290#define LMIC_ENABLE_TxParamSetupReq 1
291
292enum { DR_DFLTMIN = AS923_DR_SF10 }; // DR2
293 // DR_PAGE is a debugging parameter
294enum { DR_PAGE = DR_PAGE_AS923 };
295
296enum { FREQ_PING = AS923_F2 }; // default ping freq
297enum { DR_PING = AS923_DR_SF9 }; // default ping DR: DR3
298enum { FREQ_DNW2 = AS923_FDOWN };
299enum { DR_DNW2 = AS923_DR_SF10 };
300enum { CHNL_BCN = 5 };
301enum { FREQ_BCN = AS923_FBCN };
302enum { DR_BCN = AS923_DR_SF9 };
303enum { AIRTIME_BCN = 144384 }; // micros
304enum { LMIC_REGION_EIRP = AS923_LMIC_REGION_EIRP }; // region uses EIRP
305
306enum {
307 // Beacon frame format AS SF9
308 OFF_BCN_NETID = 0,
309 OFF_BCN_TIME = 2,
310 OFF_BCN_CRC1 = 6,
311 OFF_BCN_INFO = 8,
312 OFF_BCN_LAT = 9,
313 OFF_BCN_LON = 12,
314 OFF_BCN_CRC2 = 15,
315 LEN_BCN = 17
316};
317
318# if LMIC_DR_LEGACY
319enum _dr_configured_t {
320 DR_SF12 = AS923_DR_SF12,
321 DR_SF11 = AS923_DR_SF11,
322 DR_SF10 = AS923_DR_SF10,
323 DR_SF9 = AS923_DR_SF9,
324 DR_SF8 = AS923_DR_SF8,
325 DR_SF7 = AS923_DR_SF7,
326 DR_SF7B = AS923_DR_SF7B,
327 DR_FSK = AS923_DR_FSK,
328 DR_NONE = AS923_DR_NONE
329};
330# endif // LMIC_DR_LEGACY
331
332#elif defined(CFG_kr920) // ==============================================
333
334#include "lorabase_kr920.h"
335
336// per 2.8.3 (1.0.3 2.9.3): is not implemented
337#define LMIC_ENABLE_TxParamSetupReq 0
338
339enum { DR_DFLTMIN = KR920_DR_SF12 }; // DR2
340 // DR_PAGE is a debugging parameter
341enum { DR_PAGE = DR_PAGE_KR920 };
342
343enum { FREQ_PING = KR920_FBCN }; // default ping freq
344enum { DR_PING = KR920_DR_SF9 }; // default ping DR: DR3
345enum { FREQ_DNW2 = KR920_FDOWN };
346enum { DR_DNW2 = KR920_DR_SF12 };
347enum { CHNL_BCN = 11 };
348enum { FREQ_BCN = KR920_FBCN };
349enum { DR_BCN = KR920_DR_SF9 };
350enum { AIRTIME_BCN = 144384 }; // micros
351enum { LMIC_REGION_EIRP = KR920_LMIC_REGION_EIRP }; // region uses EIRP
352
353enum {
354 // Beacon frame format KR SF9
355 OFF_BCN_NETID = 0,
356 OFF_BCN_TIME = 2,
357 OFF_BCN_CRC1 = 6,
358 OFF_BCN_INFO = 8,
359 OFF_BCN_LAT = 9,
360 OFF_BCN_LON = 12,
361 OFF_BCN_CRC2 = 15,
362 LEN_BCN = 17
363};
364
365# if LMIC_DR_LEGACY
366enum _dr_configured_t {
367 DR_SF12 = KR920_DR_SF12,
368 DR_SF11 = KR920_DR_SF11,
369 DR_SF10 = KR920_DR_SF10,
370 DR_SF9 = KR920_DR_SF9,
371 DR_SF8 = KR920_DR_SF8,
372 DR_SF7 = KR920_DR_SF7,
373 DR_NONE = KR920_DR_NONE
374};
375# endif // LMIC_DR_LEGACY
376
377#elif defined(CFG_in866) // ==============================================
378
379#include "lorabase_in866.h"
380
381// per 2.9.3: not implemented
382#define LMIC_ENABLE_TxParamSetupReq 0
383
384enum { DR_DFLTMIN = IN866_DR_SF7 }; // DR5
385enum { DR_PAGE = DR_PAGE_IN866 }; // DR_PAGE is a debugging parameter
386
387enum { FREQ_PING = IN866_FB }; // default ping freq
388enum { DR_PING = IN866_DR_SF8 }; // default ping DR
389enum { FREQ_DNW2 = IN866_FB };
390enum { DR_DNW2 = IN866_DR_SF10 };
391enum { CHNL_BCN = 5 };
392enum { FREQ_BCN = IN866_FB };
393enum { DR_BCN = IN866_DR_SF8 };
394enum { AIRTIME_BCN = 144384 }; // micros
395enum { LMIC_REGION_EIRP = IN866_LMIC_REGION_EIRP }; // region uses EIRP
396
397enum {
398 // Beacon frame format IN SF9
399 OFF_BCN_NETID = 0,
400 OFF_BCN_TIME = 1,
401 OFF_BCN_CRC1 = 5,
402 OFF_BCN_INFO = 7,
403 OFF_BCN_LAT = 8,
404 OFF_BCN_LON = 11,
405 OFF_BCN_CRC2 = 17,
406 LEN_BCN = 19
407};
408
409# if LMIC_DR_LEGACY
410enum _dr_configured_t {
411 DR_SF12 = IN866_DR_SF12, // DR0
412 DR_SF11 = IN866_DR_SF11, // DR1
413 DR_SF10 = IN866_DR_SF10, // DR2
414 DR_SF9 = IN866_DR_SF9, // DR3
415 DR_SF8 = IN866_DR_SF8, // DR4
416 DR_SF7 = IN866_DR_SF7, // DR5
417 DR_FSK = IN866_DR_FSK, // DR7
418 DR_NONE = IN866_DR_NONE
419};
420# endif // LMIC_DR_LEGACY
421
422#else
423# error Unsupported configuration setting
424#endif // ===================================================
425
426enum {
427 // Join Request frame format
428 OFF_JR_HDR = 0,
429 OFF_JR_ARTEUI = 1,
430 OFF_JR_DEVEUI = 9,
431 OFF_JR_DEVNONCE = 17,
432 OFF_JR_MIC = 19,
433 LEN_JR = 23
434};
435enum {
436 // Join Accept frame format
437 OFF_JA_HDR = 0,
438 OFF_JA_ARTNONCE = 1,
439 OFF_JA_NETID = 4,
440 OFF_JA_DEVADDR = 7,
441 OFF_JA_RFU = 11,
442 OFF_JA_DLSET = 11,
443 OFF_JA_RXDLY = 12,
444 OFF_CFLIST = 13,
445 LEN_JA = 17,
446 LEN_JAEXT = 17+16
447};
448
449enum {
450 // JoinAccept CFList types
451 LORAWAN_JoinAccept_CFListType_FREQUENCIES = 0,
452 LORAWAN_JoinAccept_CFListType_MASK = 1,
453};
454
455enum {
456 // Data frame format
457 OFF_DAT_HDR = 0,
458 OFF_DAT_ADDR = 1,
459 OFF_DAT_FCT = 5,
460 OFF_DAT_SEQNO = 6,
461 OFF_DAT_OPTS = 8,
462};
463enum { MAX_LEN_PAYLOAD = MAX_LEN_FRAME-(int)OFF_DAT_OPTS-4 };
464enum {
465 // Bitfields in frame format octet
466 HDR_FTYPE = 0xE0,
467 HDR_RFU = 0x1C,
468 HDR_MAJOR = 0x03
469};
470enum { HDR_FTYPE_DNFLAG = 0x20 }; // flags DN frame except for HDR_FTYPE_PROP
471enum {
472 // Values of frame type bit field
473 HDR_FTYPE_JREQ = 0x00,
474 HDR_FTYPE_JACC = 0x20,
475 HDR_FTYPE_DAUP = 0x40, // data (unconfirmed) up
476 HDR_FTYPE_DADN = 0x60, // data (unconfirmed) dn
477 HDR_FTYPE_DCUP = 0x80, // data confirmed up
478 HDR_FTYPE_DCDN = 0xA0, // data confirmed dn
479 HDR_FTYPE_PROP = 0xE0
480};
481enum {
482 HDR_MAJOR_V1 = 0x00,
483};
484enum {
485 // Bitfields in frame control octet
486 FCT_ADREN = 0x80,
487 FCT_ADRACKReq = 0x40,
488 FCT_ACK = 0x20,
489 FCT_MORE = 0x10, // also in DN direction: Class B indicator
490 FCT_OPTLEN = 0x0F,
491};
492enum {
493 // In UP direction: signals class B enabled
494 FCT_CLASSB = FCT_MORE
495};
496
497enum {
498 LWAN_FCtrl_FOptsLen_MAX = 0x0Fu, // maximum size of embedded MAC commands
499};
500
501enum {
502 NWKID_MASK = (int)0xFE000000,
503 NWKID_BITS = 7
504};
505
506// MAC uplink commands downwlink too
507enum {
508 // Class A
509 MCMD_LinkCheckReq = 0x02, // -
510 MCMD_LinkADRAns = 0x03, // u1:7-3:RFU, 3/2/1: pow/DR/Ch ACK
511 MCMD_DutyCycleAns = 0x04, // -
512 MCMD_RXParamSetupAns = 0x05, // u1:7-2:RFU 1/0:datarate/channel ack
513 MCMD_DevStatusAns = 0x06, // u1:battery 0,1-254,255=?, u1:7-6:RFU,5-0:margin(-32..31)
514 MCMD_NewChannelAns = 0x07, // u1: 7-2=RFU, 1/0:DR/freq ACK
515 MCMD_RXTimingSetupAns = 0x08, // -
516 MCMD_TxParamSetupAns = 0x09, // -
517 MCMD_DlChannelAns = 0x0A, // u1: [7-2]:RFU 1:exists 0:OK
518 MCMD_DeviceTimeReq = 0x0D, // -
519
520 // Class B
521 MCMD_PingSlotInfoReq = 0x10, // u1: 7=RFU, 6-4:interval, 3-0:datarate
522 MCMD_PingSlotChannelAns = 0x11, // u1: 7-1:RFU, 0:freq ok
523 MCMD_BeaconInfoReq = 0x12, // - (DEPRECATED)
524 MCMD_BeaconFreqAns = 0x13, // u1: 7-1:RFU, 0:freq ok
525};
526
527// MAC downlink commands
528enum {
529 // Class A
530 MCMD_LinkCheckAns = 0x02, // u1:margin 0-254,255=unknown margin / u1:gwcnt LinkCheckReq
531 MCMD_LinkADRReq = 0x03, // u1:DR/TXPow, u2:chmask, u1:chpage/repeat
532 MCMD_DutyCycleReq = 0x04, // u1:255 dead [7-4]:RFU, [3-0]:cap 2^-k
533 MCMD_RXParamSetupReq = 0x05, // u1:7-4:RFU/3-0:datarate, u3:freq
534 MCMD_DevStatusReq = 0x06, // -
535 MCMD_NewChannelReq = 0x07, // u1:chidx, u3:freq, u1:DRrange
536 MCMD_RXTimingSetupReq = 0x08, // u1: [7-4]:RFU [3-0]: Delay 1-15s (0 => 1)
537 MCMD_TxParamSetupReq = 0x09, // u1: [7-6]:RFU [5:4]: dl dwell/ul dwell [3:0] max EIRP
538 MCMD_DlChannelReq = 0x0A, // u1: channel, u3: frequency
539 MCMD_DeviceTimeAns = 0x0D, // u4: seconds since epoch, u1: fractional second
540
541 // Class B
542 MCMD_PingSlotInfoAns = 0x10, // -
543 MCMD_PingSlotChannelReq = 0x11, // u3: freq, u1:dr [7-4]:RFU [3:0]:datarate
544 MCMD_BeaconTimingAns = 0x12, // u2: delay(in TUNIT millis), u1:channel (DEPRECATED)
545 MCMD_BeaconFreqReq = 0x13, // u3: freq
546};
547
548enum {
549 MCMD_BeaconTimingAns_TUNIT = 30 // time unit of delay value in millis
550};
551enum {
552 MCMD_LinkADRAns_RFU = 0xF8, // RFU bits
553 MCMD_LinkADRAns_PowerACK = 0x04, // 0=not supported power level
554 MCMD_LinkADRAns_DataRateACK = 0x02, // 0=unknown data rate
555 MCMD_LinkADRAns_ChannelACK = 0x01, // 0=unknown channel enabled
556};
557enum {
558 MCMD_RXParamSetupAns_RFU = 0xF8, // RFU bits
559 MCMD_RXParamSetupAns_RX1DrOffsetAck = 0x04, // 0=dr2 not allowed
560 MCMD_RXParamSetupAns_RX2DataRateACK = 0x02, // 0=unknown data rate
561 MCMD_RXParamSetupAns_ChannelACK = 0x01, // 0=unknown channel enabled
562};
563enum {
564 MCMD_NewChannelAns_RFU = 0xFC, // RFU bits
565 MCMD_NewChannelAns_DataRateACK = 0x02, // 0=unknown data rate
566 MCMD_NewChannelAns_ChannelACK = 0x01, // 0=rejected channel frequency
567};
568enum {
569 MCMD_RXTimingSetupReq_RFU = 0xF0, // RFU bits
570 MCMD_RXTimingSetupReq_Delay = 0x0F, // delay in secs, 1..15; 0 is mapped to 1.
571};
572enum {
573 MCMD_DlChannelAns_RFU = 0xFC, // RFU bits
574 MCMD_DlChannelAns_FreqACK = 0x02, // 0 = uplink frequency not defined for this channel
575 MCMD_DlChannelAns_ChannelACK = 0x01, // 0 = rejected channel freq
576};
577enum {
578 MCMD_PingSlotFreqAns_RFU = 0xFC,
579 MCMD_PingSlotFreqAns_DataRateACK = 0x02,
580 MCMD_PingSlotFreqAns_ChannelACK = 0x01,
581};
582
583enum {
584 MCMD_DEVS_EXT_POWER = 0x00, // external power supply
585 MCMD_DEVS_BATT_MIN = 0x01, // min battery value
586 MCMD_DEVS_BATT_MAX = 0xFE, // max battery value
587 MCMD_DEVS_BATT_NOINFO = 0xFF, // unknown battery level
588};
589
590// Bit fields byte#3 of MCMD_LinkADRReq payload
591enum {
592 MCMD_LinkADRReq_Redundancy_RFU = 0x80,
593 MCMD_LinkADRReq_Redundancy_ChMaskCntl_MASK= 0x70,
594 MCMD_LinkADRReq_Redundancy_NbTrans_MASK = 0x0F,
595
596 MCMD_LinkADRReq_ChMaskCntl_EULIKE_DIRECT = 0x00,
597 MCMD_LinkADRReq_ChMaskCntl_EULIKE_ALL_ON = 0x60,
598
599 MCMD_LinkADRReq_ChMaskCntl_USLIKE_500K = 0x40,
600 MCMD_LinkADRReq_ChMaskCntl_USLIKE_SPECIAL = 0x50,
601 MCMD_LinkADRReq_ChMaskCntl_USLIKE_BANK = 0x50,
602 MCMD_LinkADRReq_ChMaskCntl_USLIKE_125ON = 0x60,
603 MCMD_LinkADRReq_ChMaskCntl_USLIKE_125OFF = 0x70,
604
605 MCMD_LinkADRReq_ChMaskCntl_CN470_ALL_ON = 0x60,
606};
607
608// Bit fields byte#0 of MCMD_LinkADRReq payload
609enum {
610 MCMD_LinkADRReq_DR_MASK = 0xF0,
611 MCMD_LinkADRReq_POW_MASK = 0x0F,
612 MCMD_LinkADRReq_DR_SHIFT = 4,
613 MCMD_LinkADRReq_POW_SHIFT = 0,
614};
615
616// bit fields of the TxParam request
617enum {
618 MCMD_TxParam_RxDWELL_SHIFT = 5,
619 MCMD_TxParam_RxDWELL_MASK = 1 << MCMD_TxParam_RxDWELL_SHIFT,
620 MCMD_TxParam_TxDWELL_SHIFT = 4,
621 MCMD_TxParam_TxDWELL_MASK = 1 << MCMD_TxParam_TxDWELL_SHIFT,
622 MCMD_TxParam_MaxEIRP_SHIFT = 0,
623 MCMD_TxParam_MaxEIRP_MASK = 0xF << MCMD_TxParam_MaxEIRP_SHIFT,
624};
625
626// Device address
627typedef u4_t devaddr_t;
628
629// RX quality (device)
630enum { RSSI_OFF=64, SNR_SCALEUP=4 };
631
632static inline sf_t getSf (rps_t params) { return (sf_t)(params & 0x7); }
633static inline rps_t setSf (rps_t params, sf_t sf) { return (rps_t)((params & ~0x7) | sf); }
634static inline bw_t getBw (rps_t params) { return (bw_t)((params >> 3) & 0x3); }
635static inline rps_t setBw (rps_t params, bw_t cr) { return (rps_t)((params & ~0x18) | (cr<<3)); }
636static inline cr_t getCr (rps_t params) { return (cr_t)((params >> 5) & 0x3); }
637static inline rps_t setCr (rps_t params, cr_t cr) { return (rps_t)((params & ~0x60) | (cr<<5)); }
638static inline int getNocrc(rps_t params) { return ((params >> 7) & 0x1); }
639static inline rps_t setNocrc(rps_t params, int nocrc) { return (rps_t)((params & ~0x80) | (nocrc<<7)); }
640static inline int getIh (rps_t params) { return ((params >> 8) & 0xFF); }
641static inline rps_t setIh (rps_t params, int ih) { return (rps_t)((params & ~0xFF00) | (ih<<8)); }
642static inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc) {
643 return sf | (bw<<3) | (cr<<5) | (nocrc?(1<<7):0) | ((ih&0xFF)<<8);
644}
645#define MAKERPS(sf,bw,cr,ih,nocrc) ((rps_t)((sf) | ((bw)<<3) | ((cr)<<5) | ((nocrc)?(1<<7):0) | ((ih&0xFF)<<8)))
646// Two frames with params r1/r2 would interfere on air: same SFx + BWx
647static inline int sameSfBw(rps_t r1, rps_t r2) { return ((r1^r2)&0x1F) == 0; }
648static inline int isFasterDR (dr_t dr1, dr_t dr2) { return dr1 > dr2; }
649static inline int isSlowerDR (dr_t dr1, dr_t dr2) { return dr1 < dr2; }
650
651//
652// BEG: Keep in sync with lorabase.hpp
653// ================================================================================
654
655
656// Calculate airtime
657ostime_t calcAirTime (rps_t rps, u1_t plen);
658// Sensitivity at given SF/BW
659int getSensitivity (rps_t rps);
660
661#ifdef __cplusplus
662} // extern "C"
663#endif
664
665#endif // _lorabase_h_