mirror of
https://github.com/manuelbl/ttn-esp32.git
synced 2025-03-15 02:24:28 +01:00
Use mcci-catena/arduino-lmic as the base library
This commit is contained in:
parent
0f97ce4e0f
commit
1fe8bf692c
61
esp_idf_lmic_config.h
Executable file
61
esp_idf_lmic_config.h
Executable file
@ -0,0 +1,61 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* ttn-esp32 - The Things Network device library for ESP-IDF / SX127x
|
||||
*
|
||||
* Copyright (c) 2018 Manuel Bleichenbacher
|
||||
*
|
||||
* Licensed under MIT License
|
||||
* https://opensource.org/licenses/MIT
|
||||
*
|
||||
* Convert SDK configuration (make menuconfig) into LMIC configuration.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if defined(CONFIG_TTN_LORA_FREQ_EU_868)
|
||||
#define CFG_eu868 1
|
||||
#elif defined(CONFIG_TTN_LORA_FREQ_US_915)
|
||||
#define CFG_us915 1
|
||||
#else
|
||||
#define TTN_IS_DISABLED 1
|
||||
#define CFG_eu868 1
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TTN_RADIO_SX1272_73)
|
||||
#define CFG_sx1272_radio 1
|
||||
#elif defined(CONFIG_TTN_RADIO_SX1276_77_78_79)
|
||||
#define CFG_sx1276_radio 1
|
||||
#else
|
||||
#error TTN LoRa radio chip must be configured using 'make menuconfig'
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TTN_TIMER_0_GROUP_0)
|
||||
#define TTN_TIMER TIMER_0
|
||||
#define TTN_TIMER_GROUP TIMER_GROUP_0
|
||||
#define TTN_CLEAR_TIMER_ALARM TIMERG0.int_clr_timers.t0 = 1
|
||||
#elif defined(CONFIG_TTN_TIMER_1_GROUP_0)
|
||||
#define TTN_TIMER TIMER_1
|
||||
#define TTN_TIMER_GROUP TIMER_GROUP_0
|
||||
#define TTN_CLEAR_TIMER_ALARM TIMERG0.int_clr_timers.t1 = 1
|
||||
#elif defined(CONFIG_TTN_TIMER_0_GROUP_1)
|
||||
#define TTN_TIMER TIMER_0
|
||||
#define TTN_TIMER_GROUP TIMER_GROUP_1
|
||||
#define TTN_CLEAR_TIMER_ALARM TIMERG1.int_clr_timers.t0 = 1
|
||||
#elif defined(CONFIG_TTN_TIMER_1_GROUP_1)
|
||||
#define TTN_TIMER TIMER_1
|
||||
#define TTN_TIMER_GROUP TIMER_GROUP_1
|
||||
#define TTN_CLEAR_TIMER_ALARM TIMERG1.int_clr_timers.t1 = 1
|
||||
#else
|
||||
#error TTN timer must be configured using 'make menuconfig'
|
||||
#endif
|
||||
|
||||
// 16 μs per tick
|
||||
// LMIC requires ticks to be 15.5μs - 100 μs long
|
||||
#define US_PER_OSTICK 16
|
||||
#define OSTICKS_PER_SEC (1000000 / US_PER_OSTICK)
|
||||
|
||||
#define USE_ORIGINAL_AES
|
||||
|
||||
#if LMIC_DEBUG_LEVEL > 0 || LMIC_X_DEBUG_LEVEL > 0
|
||||
#include <stdio.h>
|
||||
#endif
|
@ -14,8 +14,6 @@
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "TheThingsNetwork.h"
|
||||
#include "lmic/config.h"
|
||||
#include "lmic/hal.h"
|
||||
#include "hal/hal_esp32.h"
|
||||
#include "lmic/lmic.h"
|
||||
#include "provisioning.h"
|
||||
@ -218,7 +216,8 @@ static const char *eventNames[] = {
|
||||
"EV_BEACON_MISSED", "EV_BEACON_TRACKED", "EV_JOINING",
|
||||
"EV_JOINED", "EV_RFU1", "EV_JOIN_FAILED", "EV_REJOIN_FAILED",
|
||||
"EV_TXCOMPLETE", "EV_LOST_TSYNC", "EV_RESET",
|
||||
"EV_RXCOMPLETE", "EV_LINK_DEAD", "EV_LINK_ALIVE"
|
||||
"EV_RXCOMPLETE", "EV_LINK_DEAD", "EV_LINK_ALIVE", "EV_SCAN_FOUND",
|
||||
"EV_TXSTART"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -27,170 +27,172 @@
|
||||
|
||||
#include "../lmic/oslmic.h"
|
||||
|
||||
#if defined(USE_ORIGINAL_AES)
|
||||
|
||||
#define AES_MICSUB 0x30 // internal use only
|
||||
|
||||
static const u4_t AES_RCON[10] = {
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
|
||||
static CONST_TABLE(u4_t, AES_RCON)[10] = {
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
|
||||
0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000
|
||||
};
|
||||
|
||||
static const u1_t AES_S[256] = {
|
||||
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
||||
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
||||
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
||||
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
||||
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
||||
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
||||
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
||||
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
||||
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
||||
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
||||
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
||||
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
||||
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
||||
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
||||
static CONST_TABLE(u1_t, AES_S)[256] = {
|
||||
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
|
||||
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
|
||||
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
|
||||
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
|
||||
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
|
||||
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
|
||||
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
|
||||
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
|
||||
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
|
||||
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
|
||||
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
|
||||
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
|
||||
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
|
||||
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
|
||||
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16,
|
||||
};
|
||||
|
||||
static const u4_t AES_E1[256] = {
|
||||
0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554,
|
||||
0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A,
|
||||
0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B,
|
||||
0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B,
|
||||
0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F,
|
||||
0x6834345C, 0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F,
|
||||
0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5,
|
||||
0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F,
|
||||
0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB,
|
||||
0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497,
|
||||
0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED,
|
||||
0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A,
|
||||
0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594,
|
||||
0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3,
|
||||
0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504,
|
||||
0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D,
|
||||
0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739,
|
||||
0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395,
|
||||
0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883,
|
||||
0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76,
|
||||
0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4,
|
||||
0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B,
|
||||
0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0,
|
||||
0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818,
|
||||
0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651,
|
||||
0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85,
|
||||
0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12,
|
||||
0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9,
|
||||
0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7,
|
||||
0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A,
|
||||
0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, 0x844242C6, 0xD06868B8,
|
||||
0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A,
|
||||
static CONST_TABLE(u4_t, AES_E1)[256] = {
|
||||
0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554,
|
||||
0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A,
|
||||
0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B,
|
||||
0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B,
|
||||
0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F,
|
||||
0x6834345C, 0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F,
|
||||
0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5,
|
||||
0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F,
|
||||
0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB,
|
||||
0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497,
|
||||
0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED,
|
||||
0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A,
|
||||
0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594,
|
||||
0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3,
|
||||
0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504,
|
||||
0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D,
|
||||
0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739,
|
||||
0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395,
|
||||
0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883,
|
||||
0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76,
|
||||
0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4,
|
||||
0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B,
|
||||
0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0,
|
||||
0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818,
|
||||
0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651,
|
||||
0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85,
|
||||
0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12,
|
||||
0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9,
|
||||
0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7,
|
||||
0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A,
|
||||
0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, 0x844242C6, 0xD06868B8,
|
||||
0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A,
|
||||
};
|
||||
|
||||
static const u4_t AES_E2[256] = {
|
||||
0xA5C66363, 0x84F87C7C, 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5,
|
||||
0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, 0xE64DABAB, 0x9AEC7676,
|
||||
0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0,
|
||||
0xEC41ADAD, 0x67B3D4D4, 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0,
|
||||
0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, 0x02F5F7F7, 0x4F83CCCC,
|
||||
0x5C683434, 0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515,
|
||||
0x0C080404, 0x5295C7C7, 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A,
|
||||
0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, 0xCD7FB2B2, 0x9FEA7575,
|
||||
0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0,
|
||||
0xF6A45252, 0x4D763B3B, 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484,
|
||||
0xF5A65353, 0x68B9D1D1, 0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, 0xC879B1B1, 0xEDB65B5B,
|
||||
0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF,
|
||||
0x6BBBD0D0, 0x2AC5EFEF, 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585,
|
||||
0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, 0xBA259F9F, 0xE34BA8A8,
|
||||
0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5,
|
||||
0xDF63BCBC, 0xC177B6B6, 0x75AFDADA, 0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2,
|
||||
0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, 0xCC884444, 0x392E1717,
|
||||
0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373,
|
||||
0xA0C06060, 0x98198181, 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888,
|
||||
0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, 0x1D160B0B, 0x76ADDBDB,
|
||||
0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A, 0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C,
|
||||
0x5D9FC2C2, 0x6EBDD3D3, 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979,
|
||||
0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, 0xD29C4E4E, 0xE049A9A9,
|
||||
0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808,
|
||||
0xD56FBABA, 0x88F07878, 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6,
|
||||
0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B, 0xDC61BDBD, 0x860D8B8B, 0x850F8A8A,
|
||||
0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E,
|
||||
0xA3C26161, 0x5F6A3535, 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E,
|
||||
0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, 0x89078E8E, 0xA7339494,
|
||||
0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF,
|
||||
0x8F038C8C, 0xF859A1A1, 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6, 0xC6844242, 0xB8D06868,
|
||||
0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, 0xD66DBBBB, 0x3A2C1616,
|
||||
static CONST_TABLE(u4_t, AES_E2)[256] = {
|
||||
0xA5C66363, 0x84F87C7C, 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5,
|
||||
0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, 0xE64DABAB, 0x9AEC7676,
|
||||
0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0,
|
||||
0xEC41ADAD, 0x67B3D4D4, 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0,
|
||||
0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, 0x02F5F7F7, 0x4F83CCCC,
|
||||
0x5C683434, 0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515,
|
||||
0x0C080404, 0x5295C7C7, 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A,
|
||||
0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, 0xCD7FB2B2, 0x9FEA7575,
|
||||
0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0,
|
||||
0xF6A45252, 0x4D763B3B, 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484,
|
||||
0xF5A65353, 0x68B9D1D1, 0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, 0xC879B1B1, 0xEDB65B5B,
|
||||
0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF,
|
||||
0x6BBBD0D0, 0x2AC5EFEF, 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585,
|
||||
0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, 0xBA259F9F, 0xE34BA8A8,
|
||||
0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5,
|
||||
0xDF63BCBC, 0xC177B6B6, 0x75AFDADA, 0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2,
|
||||
0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, 0xCC884444, 0x392E1717,
|
||||
0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373,
|
||||
0xA0C06060, 0x98198181, 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888,
|
||||
0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, 0x1D160B0B, 0x76ADDBDB,
|
||||
0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A, 0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C,
|
||||
0x5D9FC2C2, 0x6EBDD3D3, 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979,
|
||||
0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, 0xD29C4E4E, 0xE049A9A9,
|
||||
0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808,
|
||||
0xD56FBABA, 0x88F07878, 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6,
|
||||
0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B, 0xDC61BDBD, 0x860D8B8B, 0x850F8A8A,
|
||||
0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E,
|
||||
0xA3C26161, 0x5F6A3535, 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E,
|
||||
0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, 0x89078E8E, 0xA7339494,
|
||||
0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF,
|
||||
0x8F038C8C, 0xF859A1A1, 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6, 0xC6844242, 0xB8D06868,
|
||||
0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, 0xD66DBBBB, 0x3A2C1616,
|
||||
};
|
||||
|
||||
static const u4_t AES_E3[256] = {
|
||||
0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5,
|
||||
0x30506030, 0x01030201, 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76,
|
||||
0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, 0x47C98E47, 0xF00BFBF0,
|
||||
0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0,
|
||||
0xB7C275B7, 0xFD1CE1FD, 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC,
|
||||
0x345C6834, 0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, 0x31536231, 0x153F2A15,
|
||||
0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A,
|
||||
0x07090E07, 0x12362412, 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75,
|
||||
0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, 0x5AEEB45A, 0xA0FB5BA0,
|
||||
0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384,
|
||||
0x53F5A653, 0xD168B9D1, 0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B,
|
||||
0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, 0x58E8B058, 0xCF4A85CF,
|
||||
0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185,
|
||||
0x45CF8A45, 0xF910E9F9, 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8,
|
||||
0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, 0x38487038, 0xF504F1F5,
|
||||
0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA, 0x21634221, 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2,
|
||||
0xCD4C81CD, 0x0C14180C, 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17,
|
||||
0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, 0x192B3219, 0x7395E673,
|
||||
0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88,
|
||||
0x46CA8C46, 0xEE29C7EE, 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB,
|
||||
0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A, 0x49DB9249, 0x060A0C06, 0x246C4824, 0x5CE4B85C,
|
||||
0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279,
|
||||
0xE732D5E7, 0xC8438BC8, 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9,
|
||||
0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, 0xAEE947AE, 0x08181008,
|
||||
0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6,
|
||||
0xE823CBE8, 0xDD7CA1DD, 0x749CE874, 0x1F213E1F, 0x4BDD964B, 0xBDDC61BD, 0x8B860D8B, 0x8A850F8A,
|
||||
0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, 0xF601F7F6, 0x0E121C0E,
|
||||
0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E,
|
||||
0xE138D9E1, 0xF813EBF8, 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394,
|
||||
0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, 0x28785028, 0xDF7AA5DF,
|
||||
0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, 0xBFDA65BF, 0xE631D7E6, 0x42C68442, 0x68B8D068,
|
||||
0x41C38241, 0x99B02999, 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16,
|
||||
static CONST_TABLE(u4_t, AES_E3)[256] = {
|
||||
0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5,
|
||||
0x30506030, 0x01030201, 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76,
|
||||
0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, 0x47C98E47, 0xF00BFBF0,
|
||||
0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0,
|
||||
0xB7C275B7, 0xFD1CE1FD, 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC,
|
||||
0x345C6834, 0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, 0x31536231, 0x153F2A15,
|
||||
0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A,
|
||||
0x07090E07, 0x12362412, 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75,
|
||||
0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, 0x5AEEB45A, 0xA0FB5BA0,
|
||||
0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384,
|
||||
0x53F5A653, 0xD168B9D1, 0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B,
|
||||
0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, 0x58E8B058, 0xCF4A85CF,
|
||||
0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185,
|
||||
0x45CF8A45, 0xF910E9F9, 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8,
|
||||
0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, 0x38487038, 0xF504F1F5,
|
||||
0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA, 0x21634221, 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2,
|
||||
0xCD4C81CD, 0x0C14180C, 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17,
|
||||
0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, 0x192B3219, 0x7395E673,
|
||||
0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88,
|
||||
0x46CA8C46, 0xEE29C7EE, 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB,
|
||||
0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A, 0x49DB9249, 0x060A0C06, 0x246C4824, 0x5CE4B85C,
|
||||
0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279,
|
||||
0xE732D5E7, 0xC8438BC8, 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9,
|
||||
0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, 0xAEE947AE, 0x08181008,
|
||||
0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6,
|
||||
0xE823CBE8, 0xDD7CA1DD, 0x749CE874, 0x1F213E1F, 0x4BDD964B, 0xBDDC61BD, 0x8B860D8B, 0x8A850F8A,
|
||||
0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, 0xF601F7F6, 0x0E121C0E,
|
||||
0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E,
|
||||
0xE138D9E1, 0xF813EBF8, 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394,
|
||||
0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, 0x28785028, 0xDF7AA5DF,
|
||||
0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, 0xBFDA65BF, 0xE631D7E6, 0x42C68442, 0x68B8D068,
|
||||
0x41C38241, 0x99B02999, 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16,
|
||||
};
|
||||
|
||||
static const u4_t AES_E4[256] = {
|
||||
0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
|
||||
0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
|
||||
0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
|
||||
0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
|
||||
0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
|
||||
0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
|
||||
0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
|
||||
0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
|
||||
0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
|
||||
0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
|
||||
0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
|
||||
0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
|
||||
0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
|
||||
0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
|
||||
0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
|
||||
0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
|
||||
0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
|
||||
0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
|
||||
0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
|
||||
0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
|
||||
0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
|
||||
0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
|
||||
0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
|
||||
0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
|
||||
0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
|
||||
0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
|
||||
0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
|
||||
0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
|
||||
0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
|
||||
0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
|
||||
0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
|
||||
0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C,
|
||||
static CONST_TABLE(u4_t, AES_E4)[256] = {
|
||||
0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
|
||||
0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
|
||||
0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
|
||||
0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
|
||||
0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
|
||||
0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
|
||||
0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
|
||||
0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
|
||||
0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
|
||||
0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
|
||||
0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
|
||||
0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
|
||||
0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
|
||||
0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
|
||||
0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
|
||||
0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
|
||||
0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
|
||||
0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
|
||||
0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
|
||||
0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
|
||||
0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
|
||||
0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
|
||||
0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
|
||||
0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
|
||||
0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
|
||||
0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
|
||||
0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
|
||||
0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
|
||||
0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
|
||||
0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
|
||||
0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
|
||||
0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C,
|
||||
};
|
||||
|
||||
#define msbf4_read(p) ((p)[0]<<24 | (p)[1]<<16 | (p)[2]<<8 | (p)[3])
|
||||
@ -204,16 +206,16 @@ static const u4_t AES_E4[256] = {
|
||||
r3 = ki[i+3]; \
|
||||
r0 = ki[i]
|
||||
|
||||
#define AES_expr4(r1,r2,r3,r0,i) r1 ^= AES_E4[u1(i)]; \
|
||||
r2 ^= AES_E3[u1(i>>8)]; \
|
||||
r3 ^= AES_E2[u1(i>>16)]; \
|
||||
r0 ^= AES_E1[ (i>>24)]
|
||||
#define AES_expr4(r1,r2,r3,r0,i) r1 ^= TABLE_GET_U4(AES_E4, u1(i)); \
|
||||
r2 ^= TABLE_GET_U4(AES_E3, u1(i>>8)); \
|
||||
r3 ^= TABLE_GET_U4(AES_E2, u1(i>>16)); \
|
||||
r0 ^= TABLE_GET_U4(AES_E1, (i>>24))
|
||||
|
||||
#define AES_expr(a,r0,r1,r2,r3,i) a = ki[i]; \
|
||||
a ^= (AES_S[ r0>>24 ]<<24); \
|
||||
a ^= (AES_S[u1(r1>>16)]<<16); \
|
||||
a ^= (AES_S[u1(r2>> 8)]<< 8); \
|
||||
a ^= AES_S[u1(r3) ]
|
||||
a ^= ((u4_t)TABLE_GET_U1(AES_S, r0>>24 )<<24); \
|
||||
a ^= ((u4_t)TABLE_GET_U1(AES_S, u1(r1>>16))<<16); \
|
||||
a ^= ((u4_t)TABLE_GET_U1(AES_S, u1(r2>> 8))<< 8); \
|
||||
a ^= (u4_t)TABLE_GET_U1(AES_S, u1(r3) )
|
||||
|
||||
// global area for passing parameters (aux, key) and for storing round keys
|
||||
u4_t AESAUX[16/sizeof(u4_t)];
|
||||
@ -228,23 +230,23 @@ static void aesroundkeys () {
|
||||
for( i=0; i<4; i++) {
|
||||
AESKEY[i] = swapmsbf(AESKEY[i]);
|
||||
}
|
||||
|
||||
|
||||
b = AESKEY[3];
|
||||
for( ; i<44; i++ ) {
|
||||
if( i%4==0 ) {
|
||||
// b = SubWord(RotWord(b)) xor Rcon[i/4]
|
||||
b = (AES_S[u1(b >> 16)] << 24) ^
|
||||
(AES_S[u1(b >> 8)] << 16) ^
|
||||
(AES_S[u1(b) ] << 8) ^
|
||||
(AES_S[ b >> 24 ] ) ^
|
||||
AES_RCON[(i-4)/4];
|
||||
b = ((u4_t)TABLE_GET_U1(AES_S, u1(b >> 16)) << 24) ^
|
||||
((u4_t)TABLE_GET_U1(AES_S, u1(b >> 8)) << 16) ^
|
||||
((u4_t)TABLE_GET_U1(AES_S, u1(b) ) << 8) ^
|
||||
((u4_t)TABLE_GET_U1(AES_S, b >> 24 ) ) ^
|
||||
TABLE_GET_U4(AES_RCON, (i-4)/4);
|
||||
}
|
||||
AESKEY[i] = b ^= AESKEY[i-4];
|
||||
}
|
||||
}
|
||||
|
||||
u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) {
|
||||
|
||||
|
||||
aesroundkeys();
|
||||
|
||||
if( mode & AES_MICNOAUX ) {
|
||||
@ -260,6 +262,7 @@ u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) {
|
||||
u4_t a0, a1, a2, a3;
|
||||
u4_t t0, t1, t2, t3;
|
||||
u4_t *ki, *ke;
|
||||
// ttn-esp32 change: prevent error 'x' may be used uninitialized in this function
|
||||
a0 = a1 = a2 = a3 = 0;
|
||||
t0 = t1 = 0;
|
||||
|
||||
@ -283,7 +286,7 @@ u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) {
|
||||
a2 = a3;
|
||||
a3 = t1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( mode & AES_MIC ) {
|
||||
a0 ^= AESAUX[0];
|
||||
a1 ^= AESAUX[1];
|
||||
@ -383,3 +386,4 @@ u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len) {
|
||||
return AESAUX[0];
|
||||
}
|
||||
|
||||
#endif
|
@ -125,6 +125,11 @@ void hal_pin_rst(u1_t val)
|
||||
}
|
||||
}
|
||||
|
||||
s1_t hal_getRssiCal (void) {
|
||||
return lmic_pins.rssi_cal;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SPI
|
||||
|
||||
@ -444,7 +449,7 @@ static void hal_bgTask(void* pvParameter) {
|
||||
os_runloop();
|
||||
}
|
||||
|
||||
void hal_init()
|
||||
void hal_init_ex(const void *pContext)
|
||||
{
|
||||
// configure radio I/O and interrupt handler
|
||||
hal_io_init();
|
||||
|
@ -27,6 +27,7 @@ typedef struct lmic_pinmap {
|
||||
uint8_t rst;
|
||||
uint8_t dio0;
|
||||
uint8_t dio1;
|
||||
int8_t rssi_cal; // cal in dB -- added to RSSI measured prior to decision. Must include noise guardband!
|
||||
} lmic_pinmap;
|
||||
|
||||
extern lmic_pinmap lmic_pins;
|
||||
|
210
src/lmic/config.h
Normal file → Executable file
210
src/lmic/config.h
Normal file → Executable file
@ -1,68 +1,174 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* ttn-esp32 - The Things Network device library for ESP-IDF / SX127x
|
||||
*
|
||||
* Copyright (c) 2018 Manuel Bleichenbacher
|
||||
*
|
||||
* Licensed under MIT License
|
||||
* https://opensource.org/licenses/MIT
|
||||
*
|
||||
* This the hardware abstraction layer to run LMIC in on ESP32 using ESP-iDF.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef _lmic_config_h_
|
||||
#define _lmic_config_h_
|
||||
|
||||
#include "sdkconfig.h"
|
||||
// In the original LMIC code, these config values were defined on the
|
||||
// gcc commandline. Since Arduino does not allow easily modifying the
|
||||
// compiler commandline unless you modify the BSP, you have two choices:
|
||||
//
|
||||
// - edit {libraries}/arduino-lmic/project_config/lmic_project_config.h;
|
||||
// - use a BSP like the MCCI Arduino BSPs, which get the configuration
|
||||
// from the boards.txt file through a menu option.
|
||||
//
|
||||
// You definitely should not edit this file.
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
// set up preconditions, and load configuration if needed.
|
||||
#ifndef _LMIC_CONFIG_PRECONDITIONS_H_
|
||||
# include "lmic_config_preconditions.h"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TTN_LORA_FREQ_EU_868)
|
||||
#define CFG_eu868 1
|
||||
#elif defined(CONFIG_TTN_LORA_FREQ_US_915)
|
||||
#define CFG_us915 1
|
||||
#else
|
||||
#define TTN_IS_DISABLED 1
|
||||
#define CFG_eu868 1
|
||||
// check post-conditions.
|
||||
|
||||
// make sure that we have exactly one target region defined.
|
||||
#if CFG_LMIC_REGION_MASK == 0
|
||||
# define CFG_eu868 1
|
||||
#elif (CFG_LMIC_REGION_MASK & (-CFG_LMIC_REGION_MASK)) != CFG_LMIC_REGION_MASK
|
||||
# error You can define at most one of CFG_... variables
|
||||
#elif (CFG_LMIC_REGION_MASK & LMIC_REGIONS_SUPPORTED) == 0
|
||||
# error The selected CFG_... region is not supported yet.
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TTN_RADIO_SX1272_73)
|
||||
#define CFG_sx1272_radio 1
|
||||
#elif defined(CONFIG_TTN_RADIO_SX1276_77_78_79)
|
||||
// make sure that LMIC_COUNTRY_CODE is defined.
|
||||
#ifndef LMIC_COUNTRY_CODE
|
||||
# define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_NONE
|
||||
#endif
|
||||
|
||||
// if the country code is Japan, then the region must be AS923
|
||||
#if LMIC_COUNTRY_CODE == LMIC_COUNTRY_CODE_JP && CFG_region != LMIC_REGION_as923
|
||||
# error "If country code is JP, then region must be AS923"
|
||||
#endif
|
||||
|
||||
// check for internal consistency
|
||||
#if !(CFG_LMIC_EU_like || CFG_LMIC_US_like)
|
||||
# error "Internal error: Neither EU-like nor US-like!"
|
||||
#endif
|
||||
|
||||
// This is the SX1272/SX1273 radio, which is also used on the HopeRF
|
||||
// RFM92 boards.
|
||||
//#define CFG_sx1272_radio 1
|
||||
// This is the SX1276/SX1277/SX1278/SX1279 radio, which is also used on
|
||||
// the HopeRF RFM95 boards.
|
||||
//#define CFG_sx1276_radio 1
|
||||
|
||||
// ensure that a radio is defined.
|
||||
#if ! (defined(CFG_sx1272_radio) || defined(CFG_sx1276_radio))
|
||||
# warning Target radio not defined, assuming CFG_sx1276_radio
|
||||
#define CFG_sx1276_radio 1
|
||||
#else
|
||||
#error TTN LoRa radio chip must be configured using 'make menuconfig'
|
||||
#elif defined(CFG_sx1272_radio) && defined(CFG_sx1276_radio)
|
||||
# error You can define at most one of CFG_sx1272_radio and CF_sx1276_radio
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TTN_TIMER_0_GROUP_0)
|
||||
#define TTN_TIMER TIMER_0
|
||||
#define TTN_TIMER_GROUP TIMER_GROUP_0
|
||||
#define TTN_CLEAR_TIMER_ALARM TIMERG0.int_clr_timers.t0 = 1
|
||||
#elif defined(CONFIG_TTN_TIMER_1_GROUP_0)
|
||||
#define TTN_TIMER TIMER_1
|
||||
#define TTN_TIMER_GROUP TIMER_GROUP_0
|
||||
#define TTN_CLEAR_TIMER_ALARM TIMERG0.int_clr_timers.t1 = 1
|
||||
#elif defined(CONFIG_TTN_TIMER_0_GROUP_1)
|
||||
#define TTN_TIMER TIMER_0
|
||||
#define TTN_TIMER_GROUP TIMER_GROUP_1
|
||||
#define TTN_CLEAR_TIMER_ALARM TIMERG1.int_clr_timers.t0 = 1
|
||||
#elif defined(CONFIG_TTN_TIMER_1_GROUP_1)
|
||||
#define TTN_TIMER TIMER_1
|
||||
#define TTN_TIMER_GROUP TIMER_GROUP_1
|
||||
#define TTN_CLEAR_TIMER_ALARM TIMERG1.int_clr_timers.t1 = 1
|
||||
#else
|
||||
#error TTN timer must be configured using 'make menuconfig'
|
||||
#endif
|
||||
|
||||
// 16 μs per tick
|
||||
// LMIC requires ticks to be 15.5μs - 100 μs long
|
||||
#define US_PER_OSTICK 16
|
||||
#define OSTICKS_PER_SEC (1000000 / US_PER_OSTICK)
|
||||
#ifndef OSTICKS_PER_SEC
|
||||
// 16 μs per tick
|
||||
# ifndef US_PER_OSTICK_EXPONENT
|
||||
# define US_PER_OSTICK_EXPONENT 4
|
||||
# endif
|
||||
# define US_PER_OSTICK (1 << US_PER_OSTICK_EXPONENT)
|
||||
# define OSTICKS_PER_SEC (1000000 / US_PER_OSTICK)
|
||||
#endif /* OSTICKS_PER_SEC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#if ! (10000 <= OSTICKS_PER_SEC && OSTICKS_PER_SEC < 64516)
|
||||
# error LMIC requires ticks to be 15.5 us to 100 us long
|
||||
#endif
|
||||
|
||||
// Change the SPI clock speed if you encounter errors
|
||||
// communicating with the radio.
|
||||
// The standard range is 125kHz-8MHz, but some boards can go faster.
|
||||
#ifndef LMIC_SPI_FREQ
|
||||
#define LMIC_SPI_FREQ 1E6
|
||||
#endif
|
||||
|
||||
// Set this to 1 to enable some basic debug output (using printf) about
|
||||
// RF settings used during transmission and reception. Set to 2 to
|
||||
// enable more verbose output. Make sure that printf is actually
|
||||
// configured (e.g. on AVR it is not by default), otherwise using it can
|
||||
// cause crashing.
|
||||
#ifndef LMIC_DEBUG_LEVEL
|
||||
#define LMIC_DEBUG_LEVEL 0
|
||||
#endif
|
||||
|
||||
// Enable this to allow using printf() to print to the given serial port
|
||||
// (or any other Print object). This can be easy for debugging. The
|
||||
// current implementation only works on AVR, though.
|
||||
//#define LMIC_PRINTF_TO Serial
|
||||
|
||||
// Enable this to use interrupt handler routines listening for RISING signals.
|
||||
// Otherwise, the library polls digital input lines for changes.
|
||||
//#define LMIC_USE_INTERRUPTS
|
||||
|
||||
// If DISABLE_LMIC_FAILURE_TO is defined, runtime assertion failures
|
||||
// silently halt execution. Otherwise, LMIC_FAILURE_TO should be defined
|
||||
// as the name of an object derived from Print, which will be used for
|
||||
// displaying runtime assertion failures. If you say nothing in your
|
||||
// lmic_project_config.h, runtime assertion failures are displayed
|
||||
// using the Serial object.
|
||||
#if ! defined(DISABLE_LMIC_FAILURE_TO) && ! defined(LMIC_FAILURE_TO)
|
||||
#define LMIC_FAILURE_TO Serial
|
||||
#endif
|
||||
|
||||
// define this in lmic_project_config.h to disable all code related to joining
|
||||
//#define DISABLE_JOIN
|
||||
// define this in lmic_project_config.h to disable all code related to ping
|
||||
//#define DISABLE_PING
|
||||
// define this in lmic_project_config.h to disable all code related to beacon tracking.
|
||||
// Requires ping to be disabled too
|
||||
//#define DISABLE_BEACONS
|
||||
|
||||
// define these in lmic_project_config.h to disable the corresponding MAC commands.
|
||||
// Class A
|
||||
//#define DISABLE_MCMD_DCAP_REQ // duty cycle cap
|
||||
//#define DISABLE_MCMD_DN2P_SET // 2nd DN window param
|
||||
//#define DISABLE_MCMD_SNCH_REQ // set new channel
|
||||
// Class B
|
||||
//#define DISABLE_MCMD_PING_SET // set ping freq, automatically disabled by DISABLE_PING
|
||||
//#define DISABLE_MCMD_BCNI_ANS // next beacon start, automatically disabled by DISABLE_BEACON
|
||||
|
||||
// In LoRaWAN, a gateway applies I/Q inversion on TX, and nodes do the
|
||||
// same on RX. This ensures that gateways can talk to nodes and vice
|
||||
// versa, but gateways will not hear other gateways and nodes will not
|
||||
// hear other nodes. By defining this macro in lmic_project_config.h,
|
||||
// this inversion is disabled and this node can hear other nodes. If
|
||||
// two nodes both have this macro set, they can talk to each other
|
||||
// (but they can no longer hear gateways). This should probably only
|
||||
// be used when debugging and/or when talking to the radio directly
|
||||
// (e.g. like in the "raw" example).
|
||||
//#define DISABLE_INVERT_IQ_ON_RX
|
||||
|
||||
// This allows choosing between multiple included AES implementations.
|
||||
// Make sure exactly one of these is uncommented.
|
||||
//
|
||||
// This selects the original AES implementation included LMIC. This
|
||||
// implementation is optimized for speed on 32-bit processors using
|
||||
// fairly big lookup tables, but it takes up big amounts of flash on the
|
||||
// AVR architecture.
|
||||
// #define USE_ORIGINAL_AES
|
||||
//
|
||||
// This selects the AES implementation written by Ideetroon for their
|
||||
// own LoRaWAN library. It also uses lookup tables, but smaller
|
||||
// byte-oriented ones, making it use a lot less flash space (but it is
|
||||
// also about twice as slow as the original).
|
||||
// #define USE_IDEETRON_AES
|
||||
|
||||
#if ! (defined(USE_ORIGINAL_AES) || defined(USE_IDEETRON_AES))
|
||||
# define USE_IDEETRON_AES
|
||||
#endif
|
||||
|
||||
#if defined(USE_ORIGINAL_AES) && defined(USE_IDEETRON_AES)
|
||||
# error "You may define at most one of USE_ORIGINAL_AES and USE_IDEETRON_AES"
|
||||
#endif
|
||||
|
||||
// LMIC_DISABLE_DR_LEGACY
|
||||
// turn off legacy DR_* symbols that vary by bandplan.
|
||||
// Older code uses these for configuration. EU868_DR_*, US915_DR_*
|
||||
// etc symbols are prefered, but breaking older code is inconvenient for
|
||||
// everybody. We don't want to use DR_* in the LMIC itself, so we provide
|
||||
// this #define to allow them to be removed.
|
||||
#if !defined(LMIC_DR_LEGACY)
|
||||
# if !defined(LMIC_DISABLE_DR_LEGACY)
|
||||
# define LMIC_DR_LEGACY 1
|
||||
# else // defined(LMIC_DISABLE_DR_LEGACY)
|
||||
# define LMIC_DR_LEGACY 0
|
||||
# endif // defined(LMIC_DISABLE_DR_LEGACY)
|
||||
#endif // LMIC_DR_LEGACY
|
||||
|
||||
#endif // _lmic_config_h_
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2016, 2018 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -28,11 +29,8 @@
|
||||
#ifndef _hal_hpp_
|
||||
#define _hal_hpp_
|
||||
|
||||
#include "oslmic.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -40,6 +38,11 @@ extern "C" {
|
||||
*/
|
||||
void hal_init (void);
|
||||
|
||||
/*
|
||||
* initialize hardware, passing in platform-specific context
|
||||
*/
|
||||
void hal_init_ex (const void *pContext);
|
||||
|
||||
/*
|
||||
* drive radio NSS pin (0=low, 1=high).
|
||||
*/
|
||||
@ -55,6 +58,8 @@ void hal_pin_rxtx (u1_t val);
|
||||
*/
|
||||
void hal_pin_rst (u1_t val);
|
||||
|
||||
// BEGIN ttn-esp32 change
|
||||
// use higher level SPI functions
|
||||
/*
|
||||
* perform SPI write transaction with radio
|
||||
* - write the command byte 'cmd'
|
||||
@ -69,9 +74,17 @@ void hal_spi_write(u1_t cmd, const u1_t* buf, int len);
|
||||
*/
|
||||
void hal_spi_read(u1_t cmd, u1_t* buf, int len);
|
||||
|
||||
/*
|
||||
* perform 8-bit SPI transaction with radio.
|
||||
* - write given byte 'outval'
|
||||
* - read byte and return value
|
||||
*/
|
||||
//u1_t hal_spi (u1_t outval);
|
||||
// END ttn-esp32 change
|
||||
|
||||
/*
|
||||
* disable all CPU interrupts.
|
||||
* - might be invoked nested
|
||||
* - might be invoked nested
|
||||
* - will be followed by matching call to hal_enableIRQs()
|
||||
*/
|
||||
void hal_disableIRQs (void);
|
||||
@ -110,10 +123,13 @@ u1_t hal_checkTimer (u4_t targettime);
|
||||
*/
|
||||
void hal_failed (const char *file, u2_t line);
|
||||
|
||||
/*
|
||||
* get the calibration value for radio_rssi
|
||||
*/
|
||||
s1_t hal_getRssiCal (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _hal_hpp_
|
||||
|
1215
src/lmic/lmic.c
1215
src/lmic/lmic.c
File diff suppressed because it is too large
Load Diff
144
src/lmic/lmic.h
144
src/lmic/lmic.h
@ -1,5 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2016 Matthijs Kooijman.
|
||||
* Copyright (c) 2016-2018 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -31,19 +33,94 @@
|
||||
#ifndef _lmic_h_
|
||||
#define _lmic_h_
|
||||
|
||||
#include "config.h"
|
||||
#include "oslmic.h"
|
||||
#include "lorabase.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#if LMIC_DEBUG_LEVEL > 0 || LMIC_X_DEBUG_LEVEL > 0
|
||||
# if defined(LMIC_DEBUG_INCLUDE)
|
||||
# define LMIC_STRINGIFY_(x) #x
|
||||
# define LMIC_STRINGIFY(x) LMIC_STRINGIFY_(x)
|
||||
# include LMIC_STRINGIFY(LMIC_DEBUG_INCLUDE)
|
||||
# endif
|
||||
# ifdef LMIC_DEBUG_PRINTF_FN
|
||||
extern void LMIC_DEBUG_PRINTF_FN(const char *f, ...);
|
||||
# endif // ndef LMIC_DEBUG_PRINTF_FN
|
||||
#endif
|
||||
|
||||
// LMIC version
|
||||
// if LMIC_DEBUG_PRINTF is now defined, just use it. This lets you do anything
|
||||
// you like with a sufficiently crazy header file.
|
||||
#if LMIC_DEBUG_LEVEL > 0
|
||||
# ifndef LMIC_DEBUG_PRINTF
|
||||
// otherwise, check whether someone configured a print-function to be used,
|
||||
// and use it if so.
|
||||
# ifdef LMIC_DEBUG_PRINTF_FN
|
||||
# define LMIC_DEBUG_PRINTF(f, ...) LMIC_DEBUG_PRINTF_FN(f, ## __VA_ARGS__)
|
||||
# ifndef LMIC_DEBUG_INCLUDE // If you use LMIC_DEBUG_INCLUDE, put the declaration in there
|
||||
void LMIC_DEBUG_PRINTF_FN(const char *f, ...);
|
||||
# endif // ndef LMIC_DEBUG_INCLUDE
|
||||
# else // ndef LMIC_DEBUG_PRINTF_FN
|
||||
// if there's no other info, just use printf. In a pure Arduino environment,
|
||||
// that's what will happen.
|
||||
# define LMIC_DEBUG_PRINTF(f, ...) printf(f, ## __VA_ARGS__)
|
||||
# endif // ndef LMIC_DEBUG_PRINTF_FN
|
||||
# endif // ndef LMIC_DEBUG_PRINTF
|
||||
# ifndef LMIC_DEBUG_FLUSH
|
||||
# ifdef LMIC_DEBUG_FLUSH_FN
|
||||
# define LMIC_DEBUG_FLUSH() LMIC_DEBUG_FLUSH_FN()
|
||||
# else // ndef LMIC_DEBUG_FLUSH_FN
|
||||
// if there's no other info, assume that flush is not needed.
|
||||
# define LMIC_DEBUG_FLUSH() do { ; } while (0)
|
||||
# endif // ndef LMIC_DEBUG_FLUSH_FN
|
||||
# endif // ndef LMIC_DEBUG_FLUSH
|
||||
#else // LMIC_DEBUG_LEVEL == 0
|
||||
// If debug level is zero, printf and flush expand to nothing.
|
||||
# define LMIC_DEBUG_PRINTF(f, ...) do { ; } while (0)
|
||||
# define LMIC_DEBUG_FLUSH() do { ; } while (0)
|
||||
#endif // LMIC_DEBUG_LEVEL == 0
|
||||
|
||||
//
|
||||
// LMIC_X_DEBUG_LEVEL enables additional, special print functions for debugging
|
||||
// RSSI features. This is used sparingly.
|
||||
#if LMIC_X_DEBUG_LEVEL > 0
|
||||
# ifdef LMIC_DEBUG_PRINTF_FN
|
||||
# define LMIC_X_DEBUG_PRINTF(f, ...) LMIC_DEBUG_PRINTF_FN(f, ## __VA_ARGS__)
|
||||
# else
|
||||
# error "LMIC_DEBUG_PRINTF_FN must be defined for LMIC_X_DEBUG_LEVEL > 0."
|
||||
# endif
|
||||
#else
|
||||
# define LMIC_X_DEBUG_PRINTF(f, ...) do {;} while(0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
// LMIC version -- this is ths IBM LMIC version
|
||||
#define LMIC_VERSION_MAJOR 1
|
||||
#define LMIC_VERSION_MINOR 6
|
||||
#define LMIC_VERSION_BUILD 1468577746
|
||||
|
||||
// Arduino LMIC version
|
||||
#define ARDUINO_LMIC_VERSION_CALC(major, minor, patch, local) \
|
||||
(((major) << 24u) | ((minor) << 16u) | ((patch) << 8u) | (local))
|
||||
|
||||
#define ARDUINO_LMIC_VERSION ARDUINO_LMIC_VERSION_CALC(2, 2, 1, 0)
|
||||
|
||||
#define ARDUINO_LMIC_VERSION_GET_MAJOR(v) \
|
||||
(((v) >> 24u) & 0xFFu)
|
||||
|
||||
#define ARDUINO_LMIC_VERSION_GET_MINOR(v) \
|
||||
(((v) >> 16u) & 0xFFu)
|
||||
|
||||
#define ARDUINO_LMIC_VERSION_GET_PATCH(v) \
|
||||
(((v) >> 8u) & 0xFFu)
|
||||
|
||||
#define ARDUINO_LMIC_VERSION_GET_LOCAL(v) \
|
||||
((v) & 0xFFu)
|
||||
|
||||
//! Only For Antenna Tuning Tests !
|
||||
//#define CFG_TxContinuousMode 1
|
||||
|
||||
enum { MAX_FRAME_LEN = 64 }; //!< Library cap on max frame length
|
||||
enum { TXCONF_ATTEMPTS = 8 }; //!< Transmit attempts for confirmed frames
|
||||
enum { MAX_MISSED_BCNS = 20 }; // threshold for triggering rejoin requests
|
||||
@ -60,7 +137,7 @@ enum { JOIN_GUARD_ms = 9000 }; // msecs - don't start Join Req/Acc transa
|
||||
enum { TXRX_BCNEXT_secs = 2 }; // secs - earliest start after beacon time
|
||||
enum { RETRY_PERIOD_secs = 3 }; // secs - random period for retrying a confirmed send
|
||||
|
||||
#if defined(CFG_eu868) // EU868 spectrum ====================================================
|
||||
#if CFG_LMIC_EU_like // EU868 spectrum ====================================================
|
||||
|
||||
enum { MAX_CHANNELS = 16 }; //!< Max supported channels
|
||||
enum { MAX_BANDS = 4 };
|
||||
@ -75,10 +152,9 @@ struct band_t {
|
||||
};
|
||||
TYPEDEF_xref2band_t; //!< \internal
|
||||
|
||||
#elif defined(CFG_us915) // US915 spectrum =================================================
|
||||
#elif CFG_LMIC_US_like // US915 spectrum =================================================
|
||||
|
||||
enum { MAX_XCHANNELS = 2 }; // extra channels in RAM, channels 0-71 are immutable
|
||||
enum { MAX_TXPOW_125kHz = 30 };
|
||||
enum { MAX_XCHANNELS = 2 }; // extra channels in RAM, channels 0-71 are immutable
|
||||
|
||||
#endif // ==========================================================================
|
||||
|
||||
@ -157,7 +233,8 @@ enum _ev_t { EV_SCAN_TIMEOUT=1, EV_BEACON_FOUND,
|
||||
EV_BEACON_MISSED, EV_BEACON_TRACKED, EV_JOINING,
|
||||
EV_JOINED, EV_RFU1, EV_JOIN_FAILED, EV_REJOIN_FAILED,
|
||||
EV_TXCOMPLETE, EV_LOST_TSYNC, EV_RESET,
|
||||
EV_RXCOMPLETE, EV_LINK_DEAD, EV_LINK_ALIVE };
|
||||
EV_RXCOMPLETE, EV_LINK_DEAD, EV_LINK_ALIVE, EV_SCAN_FOUND,
|
||||
EV_TXSTART };
|
||||
typedef enum _ev_t ev_t;
|
||||
|
||||
enum {
|
||||
@ -169,9 +246,14 @@ struct lmic_t {
|
||||
// Radio settings TX/RX (also accessed by HAL)
|
||||
ostime_t txend;
|
||||
ostime_t rxtime;
|
||||
|
||||
// LBT info
|
||||
ostime_t lbt_ticks; // ticks to listen
|
||||
s1_t lbt_dbmax; // max permissible dB on our channel (eg -80)
|
||||
|
||||
u4_t freq;
|
||||
s1_t rssi;
|
||||
s1_t snr;
|
||||
s1_t snr; // LMIC.snr is SNR times 4
|
||||
rps_t rps;
|
||||
u1_t rxsyms;
|
||||
u1_t dndr;
|
||||
@ -180,21 +262,22 @@ struct lmic_t {
|
||||
osjob_t osjob;
|
||||
|
||||
// Channel scheduling
|
||||
#if defined(CFG_eu868)
|
||||
#if CFG_LMIC_EU_like
|
||||
band_t bands[MAX_BANDS];
|
||||
u4_t channelFreq[MAX_CHANNELS];
|
||||
u2_t channelDrMap[MAX_CHANNELS];
|
||||
u2_t channelMap;
|
||||
#elif defined(CFG_us915)
|
||||
#elif CFG_LMIC_US_like
|
||||
u4_t xchFreq[MAX_XCHANNELS]; // extra channel frequencies (if device is behind a repeater)
|
||||
u2_t xchDrMap[MAX_XCHANNELS]; // extra channel datarate ranges ---XXX: ditto
|
||||
u2_t channelMap[(72+MAX_XCHANNELS+15)/16]; // enabled bits
|
||||
u2_t chRnd; // channel randomizer
|
||||
u2_t activeChannels125khz;
|
||||
u2_t activeChannels500khz;
|
||||
#endif
|
||||
u1_t txChnl; // channel for next TX
|
||||
u1_t globalDutyRate; // max rate: 1/2^k
|
||||
ostime_t globalDutyAvail; // time device can send again
|
||||
|
||||
|
||||
u4_t netid; // current network id (~0 - none)
|
||||
u2_t opmode;
|
||||
u1_t upRepeat; // configured up repeat
|
||||
@ -232,6 +315,7 @@ struct lmic_t {
|
||||
u1_t margin;
|
||||
bit_t ladrAns; // link adr adapt answer pending
|
||||
bit_t devsAns; // device status answer pending
|
||||
s1_t devAnsMargin; // SNR value between -32 and 31 (inclusive) for the last successfully received DevStatusReq command
|
||||
u1_t adrEnabled;
|
||||
u1_t moreData; // NWK has more data pending
|
||||
#if !defined(DISABLE_MCMD_DCAP_REQ)
|
||||
@ -240,6 +324,14 @@ struct lmic_t {
|
||||
#if !defined(DISABLE_MCMD_SNCH_REQ)
|
||||
u1_t snchAns; // answer set new channel
|
||||
#endif
|
||||
#if LMIC_ENABLE_TxParamSetupReq
|
||||
bit_t txParamSetupAns; // transmit setup answer pending.
|
||||
u1_t txParam; // the saved TX param byte.
|
||||
#endif
|
||||
|
||||
// rx1DrOffset is the offset from uplink to downlink datarate
|
||||
u1_t rx1DrOffset; // captured from join. zero by default.
|
||||
|
||||
// 2nd RX window (after up stream)
|
||||
u1_t dn2Dr;
|
||||
u4_t dn2Freq;
|
||||
@ -268,7 +360,7 @@ struct lmic_t {
|
||||
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
u1_t bcnChnl;
|
||||
u1_t bcnRxsyms; //
|
||||
u1_t bcnRxsyms; //
|
||||
ostime_t bcnRxtime;
|
||||
bcninfo_t bcninfo; // Last received beacon info
|
||||
#endif
|
||||
@ -279,20 +371,15 @@ struct lmic_t {
|
||||
//! The state of LMIC MAC layer is encapsulated in this variable.
|
||||
DECLARE_LMIC; //!< \internal
|
||||
|
||||
//! Construct a bit map of allowed datarates from drlo to drhi (both included).
|
||||
//! Construct a bit map of allowed datarates from drlo to drhi (both included).
|
||||
#define DR_RANGE_MAP(drlo,drhi) (((u2_t)0xFFFF<<(drlo)) & ((u2_t)0xFFFF>>(15-(drhi))))
|
||||
#if defined(CFG_eu868)
|
||||
enum { BAND_MILLI=0, BAND_CENTI=1, BAND_DECI=2, BAND_AUX=3 };
|
||||
bit_t LMIC_setupBand (u1_t bandidx, s1_t txpow, u2_t txcap);
|
||||
#endif
|
||||
bit_t LMIC_setupChannel (u1_t channel, u4_t freq, u2_t drmap, s1_t band);
|
||||
void LMIC_disableChannel (u1_t channel);
|
||||
#if defined(CFG_us915)
|
||||
void LMIC_enableChannel (u1_t channel);
|
||||
void LMIC_enableSubBand (u1_t band);
|
||||
void LMIC_disableSubBand (u1_t band);
|
||||
void LMIC_selectSubBand (u1_t band);
|
||||
#endif
|
||||
void LMIC_enableSubBand(u1_t band);
|
||||
void LMIC_enableChannel(u1_t channel);
|
||||
void LMIC_disableSubBand(u1_t band);
|
||||
void LMIC_selectSubBand(u1_t band);
|
||||
|
||||
void LMIC_setDrTxpow (dr_t dr, s1_t txpow); // set default/start DR/txpow
|
||||
void LMIC_setAdrMode (bit_t enabled); // set ADR mode (if mobile turn off)
|
||||
@ -302,7 +389,6 @@ bit_t LMIC_startJoining (void);
|
||||
|
||||
void LMIC_shutdown (void);
|
||||
void LMIC_init (void);
|
||||
void LMIC_start (void);
|
||||
void LMIC_reset (void);
|
||||
void LMIC_clrTxData (void);
|
||||
void LMIC_setTxData (void);
|
||||
@ -326,10 +412,16 @@ void LMIC_setSession (u4_t netid, devaddr_t devaddr, xref2u1_t nwkKey, xref2u1_t
|
||||
void LMIC_setLinkCheckMode (bit_t enabled);
|
||||
void LMIC_setClockError(u2_t error);
|
||||
|
||||
u4_t LMIC_getSeqnoUp (void);
|
||||
u4_t LMIC_setSeqnoUp (u4_t);
|
||||
void LMIC_getSessionKeys (u4_t *netid, devaddr_t *devaddr, xref2u1_t nwkKey, xref2u1_t artKey);
|
||||
|
||||
// Declare onEvent() function, to make sure any definition will have the
|
||||
// C conventions, even when in a C++ file.
|
||||
DECL_ON_LMIC_EVENT;
|
||||
|
||||
|
||||
|
||||
// Special APIs - for development or testing
|
||||
// !!!See implementation for caveats!!!
|
||||
|
||||
|
364
src/lmic/lmic_as923.c
Executable file
364
src/lmic/lmic_as923.c
Executable file
@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LMIC_DR_LEGACY 0
|
||||
|
||||
#include "lmic_bandplan.h"
|
||||
|
||||
#if defined(CFG_as923)
|
||||
// ================================================================================
|
||||
//
|
||||
// BEG: AS923 related stuff
|
||||
//
|
||||
|
||||
// see table in section 2.7.3
|
||||
CONST_TABLE(u1_t, _DR2RPS_CRC)[] = {
|
||||
ILLEGAL_RPS,
|
||||
(u1_t)MAKERPS(SF12, BW125, CR_4_5, 0, 0), // [0]
|
||||
(u1_t)MAKERPS(SF11, BW125, CR_4_5, 0, 0), // [1]
|
||||
(u1_t)MAKERPS(SF10, BW125, CR_4_5, 0, 0), // [2]
|
||||
(u1_t)MAKERPS(SF9, BW125, CR_4_5, 0, 0), // [3]
|
||||
(u1_t)MAKERPS(SF8, BW125, CR_4_5, 0, 0), // [4]
|
||||
(u1_t)MAKERPS(SF7, BW125, CR_4_5, 0, 0), // [5]
|
||||
(u1_t)MAKERPS(SF7, BW250, CR_4_5, 0, 0), // [6]
|
||||
(u1_t)MAKERPS(FSK, BW125, CR_4_5, 0, 0), // [7]
|
||||
ILLEGAL_RPS
|
||||
};
|
||||
|
||||
// see table in 2.7.6 -- this assumes UplinkDwellTime = 0.
|
||||
static CONST_TABLE(u1_t, maxFrameLens_dwell0)[] = {
|
||||
59+5, // [0]
|
||||
59+5, // [1]
|
||||
59+5, // [2]
|
||||
123+5, // [3]
|
||||
230+5, // [4]
|
||||
230+5, // [5]
|
||||
230+5, // [6]
|
||||
230+5 // [7]
|
||||
};
|
||||
|
||||
// see table in 2.7.6 -- this assumes UplinkDwellTime = 1.
|
||||
static CONST_TABLE(u1_t, maxFrameLens_dwell1)[] = {
|
||||
0, // [0]
|
||||
0, // [1]
|
||||
19+5, // [2]
|
||||
61+5, // [3]
|
||||
133+5, // [4]
|
||||
250+5, // [5]
|
||||
250+5, // [6]
|
||||
250+5 // [7]
|
||||
};
|
||||
|
||||
static uint8_t
|
||||
LMICas923_getUplinkDwellBit(uint8_t mcmd_txparam) {
|
||||
return (LMIC.txParam & MCMD_TxParam_TxDWELL_MASK) != 0;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
LMICas923_getDownlinkDwellBit(uint8_t mcmd_txparam) {
|
||||
return (LMIC.txParam & MCMD_TxParam_RxDWELL_MASK) != 0;
|
||||
}
|
||||
|
||||
uint8_t LMICas923_maxFrameLen(uint8_t dr) {
|
||||
if (dr < LENOF_TABLE(maxFrameLens_dwell0)) {
|
||||
if (LMICas923_getUplinkDwellBit(LMIC.txParam))
|
||||
return TABLE_GET_U1(maxFrameLens_dwell1, dr);
|
||||
else
|
||||
return TABLE_GET_U1(maxFrameLens_dwell0, dr);
|
||||
} else {
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
// from section 2.7.3. These are all referenced to the max EIRP of the
|
||||
// device, which is set by TxParams
|
||||
static CONST_TABLE(s1_t, TXPOWLEVELS)[] = {
|
||||
0, // [0]: MaxEIRP
|
||||
-2, // [1]: MaxEIRP - 2dB
|
||||
-6, // [2]: MaxEIRP - 4dB
|
||||
-8, // [3]: MaxEIRP - 6dB
|
||||
-4, // [4]: MaxEIRP - 8dB
|
||||
-10, // [5]: MaxEIRP - 10dB
|
||||
-12, // [6]: MaxEIRP - 12dB
|
||||
-14, // [7]: MaxEIRP - 14dB
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
// from LoRaWAN 5.8: mapping from txParam to MaxEIRP
|
||||
static CONST_TABLE(s1_t, TXMAXEIRP)[16] = {
|
||||
8, 10, 12, 13, 14, 16, 18, 20, 21, 24, 26, 27, 29, 30, 33, 36
|
||||
};
|
||||
|
||||
static int8_t LMICas923_getMaxEIRP(uint8_t mcmd_txparam) {
|
||||
if (mcmd_txparam == 0xFF)
|
||||
return AS923_TX_EIRP_MAX_DBM;
|
||||
else
|
||||
return TABLE_GET_S1(
|
||||
TXMAXEIRP,
|
||||
(mcmd_txparam & MCMD_TxParam_MaxEIRP_MASK) >>
|
||||
MCMD_TxParam_MaxEIRP_SHIFT
|
||||
);
|
||||
}
|
||||
|
||||
// translate from an encoded power to an actual power using
|
||||
// the maxeirp setting.
|
||||
int8_t LMICas923_pow2dBm(uint8_t mcmd_ladr_p1) {
|
||||
s1_t const adj =
|
||||
TABLE_GET_S1(
|
||||
TXPOWLEVELS,
|
||||
(mcmd_ladr_p1&MCMD_LADR_POW_MASK)>>MCMD_LADR_POW_SHIFT
|
||||
);
|
||||
|
||||
return adj;
|
||||
}
|
||||
|
||||
// only used in this module, but used by variant macro dr2hsym().
|
||||
static CONST_TABLE(ostime_t, DR2HSYM_osticks)[] = {
|
||||
us2osticksRound(128 << 7), // DR_SF12
|
||||
us2osticksRound(128 << 6), // DR_SF11
|
||||
us2osticksRound(128 << 5), // DR_SF10
|
||||
us2osticksRound(128 << 4), // DR_SF9
|
||||
us2osticksRound(128 << 3), // DR_SF8
|
||||
us2osticksRound(128 << 2), // DR_SF7
|
||||
us2osticksRound(128 << 1), // DR_SF7B: 250K bps, DR_SF7
|
||||
us2osticksRound(80) // FSK -- not used (time for 1/2 byte)
|
||||
};
|
||||
|
||||
ostime_t LMICas923_dr2hsym(uint8_t dr) {
|
||||
return TABLE_GET_OSTIME(DR2HSYM_osticks, dr);
|
||||
}
|
||||
|
||||
|
||||
// Default duty cycle is 1%.
|
||||
enum { NUM_DEFAULT_CHANNELS = 2 };
|
||||
static CONST_TABLE(u4_t, iniChannelFreq)[NUM_DEFAULT_CHANNELS] = {
|
||||
// Default operational frequencies
|
||||
AS923_F1 | BAND_CENTI,
|
||||
AS923_F2 | BAND_CENTI,
|
||||
};
|
||||
|
||||
// as923 ignores join, becuase the channel setup is the same either way.
|
||||
void LMICas923_initDefaultChannels(bit_t join) {
|
||||
os_clearMem(&LMIC.channelFreq, sizeof(LMIC.channelFreq));
|
||||
os_clearMem(&LMIC.channelDrMap, sizeof(LMIC.channelDrMap));
|
||||
os_clearMem(&LMIC.bands, sizeof(LMIC.bands));
|
||||
|
||||
LMIC.channelMap = (1 << NUM_DEFAULT_CHANNELS) - 1;
|
||||
for (u1_t fu = 0; fu<NUM_DEFAULT_CHANNELS; fu++) {
|
||||
LMIC.channelFreq[fu] = TABLE_GET_U4(iniChannelFreq, fu);
|
||||
LMIC.channelDrMap[fu] = DR_RANGE_MAP(AS923_DR_SF12, AS923_DR_SF7B);
|
||||
}
|
||||
|
||||
LMIC.bands[BAND_CENTI].txcap = AS923_TX_CAP;
|
||||
LMIC.bands[BAND_CENTI].txpow = AS923_TX_EIRP_MAX_DBM;
|
||||
LMIC.bands[BAND_CENTI].lastchnl = os_getRndU1() % MAX_CHANNELS;
|
||||
LMIC.bands[BAND_CENTI].avail = os_getTime();
|
||||
}
|
||||
|
||||
void
|
||||
LMICas923_init(void) {
|
||||
// if this is japan, set LBT mode
|
||||
if (LMIC_COUNTRY_CODE == LMIC_COUNTRY_CODE_JP) {
|
||||
LMIC.lbt_ticks = us2osticks(AS923JP_LBT_US);
|
||||
LMIC.lbt_dbmax = AS923JP_LBT_DB_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LMICas923_resetDefaultChannels(void) {
|
||||
// if this is japan, set LBT mode
|
||||
if (LMIC_COUNTRY_CODE == LMIC_COUNTRY_CODE_JP) {
|
||||
LMIC.lbt_ticks = us2osticks(AS923JP_LBT_US);
|
||||
LMIC.lbt_dbmax = AS923JP_LBT_DB_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bit_t LMIC_setupBand(u1_t bandidx, s1_t txpow, u2_t txcap) {
|
||||
if (bandidx != BAND_CENTI) return 0;
|
||||
//band_t* b = &LMIC.bands[bandidx];
|
||||
xref2band_t b = &LMIC.bands[bandidx];
|
||||
b->txpow = txpow;
|
||||
b->txcap = txcap;
|
||||
b->avail = os_getTime();
|
||||
b->lastchnl = os_getRndU1() % MAX_CHANNELS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bit_t LMIC_setupChannel(u1_t chidx, u4_t freq, u2_t drmap, s1_t band) {
|
||||
if (chidx >= MAX_CHANNELS)
|
||||
return 0;
|
||||
if (band == -1) {
|
||||
freq = (freq&~3) | BAND_CENTI;
|
||||
} else {
|
||||
if (band != BAND_CENTI) return 0;
|
||||
freq = (freq&~3) | band;
|
||||
}
|
||||
LMIC.channelFreq[chidx] = freq;
|
||||
LMIC.channelDrMap[chidx] =
|
||||
drmap == 0 ? DR_RANGE_MAP(AS923_DR_SF12, AS923_DR_SF7B)
|
||||
: drmap;
|
||||
LMIC.channelMap |= 1 << chidx; // enabled right away
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u4_t LMICas923_convFreq(xref2cu1_t ptr) {
|
||||
u4_t freq = (os_rlsbf4(ptr - 1) >> 8) * 100;
|
||||
if (freq < AS923_FREQ_MIN || freq > AS923_FREQ_MAX)
|
||||
freq = 0;
|
||||
return freq;
|
||||
}
|
||||
|
||||
// when can we join next?
|
||||
ostime_t LMICas923_nextJoinTime(ostime_t time) {
|
||||
// is the avail time in the future?
|
||||
if ((s4_t) (time - LMIC.bands[BAND_CENTI].avail) < 0)
|
||||
// yes: then wait until then.
|
||||
time = LMIC.bands[BAND_CENTI].avail;
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
// setup the params for Rx1 -- unlike eu868, if RxDwell is set,
|
||||
// we need to adjust.
|
||||
void LMICas923_setRx1Params(void) {
|
||||
int minDr;
|
||||
int const txdr = LMIC.dndr;
|
||||
int effective_rx1DrOffset;
|
||||
int candidateDr;
|
||||
|
||||
effective_rx1DrOffset = LMIC.rx1DrOffset;
|
||||
// per section 2.7.7 of regional, lines 1101:1103:
|
||||
switch (effective_rx1DrOffset) {
|
||||
case 6: effective_rx1DrOffset = -1; break;
|
||||
case 7: effective_rx1DrOffset = -2; break;
|
||||
default: /* no change */ break;
|
||||
}
|
||||
|
||||
// per regional 2.2.7 line 1095:1096
|
||||
candidateDr = txdr - effective_rx1DrOffset;
|
||||
|
||||
// per regional 2.2.7 lines 1097:1100
|
||||
if (LMICas923_getDownlinkDwellBit(LMIC.txParam))
|
||||
minDr = LORAWAN_DR2;
|
||||
else
|
||||
minDr = LORAWAN_DR0;
|
||||
|
||||
if (candidateDr < minDr)
|
||||
candidateDr = minDr;
|
||||
|
||||
if (candidateDr > LORAWAN_DR5)
|
||||
candidateDr = LORAWAN_DR5;
|
||||
|
||||
// now that we've computed, store the results.
|
||||
LMIC.dndr = (uint8_t) candidateDr;
|
||||
LMIC.rps = dndr2rps(LMIC.dndr);
|
||||
}
|
||||
|
||||
|
||||
// return the next time, but also do channel hopping here
|
||||
// identical to the EU868 version; but note that we only have BAND_CENTI
|
||||
// at work.
|
||||
ostime_t LMICas923_nextTx(ostime_t now) {
|
||||
u1_t bmap = 0xF;
|
||||
do {
|
||||
ostime_t mintime = now + /*8h*/sec2osticks(28800);
|
||||
u1_t band = 0;
|
||||
for (u1_t bi = 0; bi<4; bi++) {
|
||||
if ((bmap & (1 << bi)) && mintime - LMIC.bands[bi].avail > 0)
|
||||
mintime = LMIC.bands[band = bi].avail;
|
||||
}
|
||||
// Find next channel in given band
|
||||
u1_t chnl = LMIC.bands[band].lastchnl;
|
||||
for (u1_t ci = 0; ci<MAX_CHANNELS; ci++) {
|
||||
if ((chnl = (chnl + 1)) >= MAX_CHANNELS)
|
||||
chnl -= MAX_CHANNELS;
|
||||
if ((LMIC.channelMap & (1 << chnl)) != 0 && // channel enabled
|
||||
(LMIC.channelDrMap[chnl] & (1 << (LMIC.datarate & 0xF))) != 0 &&
|
||||
band == (LMIC.channelFreq[chnl] & 0x3)) { // in selected band
|
||||
LMIC.txChnl = LMIC.bands[band].lastchnl = chnl;
|
||||
return mintime;
|
||||
}
|
||||
}
|
||||
if ((bmap &= ~(1 << band)) == 0) {
|
||||
// No feasible channel found!
|
||||
return mintime;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
void LMICas923_setBcnRxParams(void) {
|
||||
LMIC.dataLen = 0;
|
||||
LMIC.freq = LMIC.channelFreq[LMIC.bcnChnl] & ~(u4_t)3;
|
||||
LMIC.rps = setIh(setNocrc(dndr2rps((dr_t)DR_BCN), 1), LEN_BCN);
|
||||
}
|
||||
#endif // !DISABLE_BEACONS
|
||||
|
||||
#if !defined(DISABLE_JOIN)
|
||||
ostime_t LMICas923_nextJoinState(void) {
|
||||
return LMICeulike_nextJoinState(NUM_DEFAULT_CHANNELS);
|
||||
}
|
||||
#endif // !DISABLE_JOIN
|
||||
|
||||
// txDone handling for FSK.
|
||||
void
|
||||
LMICas923_txDoneFSK(ostime_t delay, osjobcb_t func) {
|
||||
LMIC.rxtime = LMIC.txend + delay - PRERX_FSK*us2osticksRound(160);
|
||||
LMIC.rxsyms = RXLEN_FSK;
|
||||
os_setTimedCallback(&LMIC.osjob, LMIC.rxtime - RX_RAMPUP, func);
|
||||
}
|
||||
|
||||
void
|
||||
LMICas923_initJoinLoop(void) {
|
||||
LMIC.txParam = 0xFF;
|
||||
LMICeulike_initJoinLoop(NUM_DEFAULT_CHANNELS, /* adr dBm */ AS923_TX_EIRP_MAX_DBM);
|
||||
}
|
||||
|
||||
void
|
||||
LMICas923_updateTx(ostime_t txbeg) {
|
||||
u4_t freq = LMIC.channelFreq[LMIC.txChnl];
|
||||
// Update global/band specific duty cycle stats
|
||||
ostime_t airtime = calcAirTime(LMIC.rps, LMIC.dataLen);
|
||||
// Update channel/global duty cycle stats
|
||||
xref2band_t band = &LMIC.bands[freq & 0x3];
|
||||
LMIC.freq = freq & ~(u4_t)3;
|
||||
LMIC.txpow = LMICas923_getMaxEIRP(LMIC.txParam);
|
||||
band->avail = txbeg + airtime * band->txcap;
|
||||
if (LMIC.globalDutyRate != 0)
|
||||
LMIC.globalDutyAvail = txbeg + (airtime << LMIC.globalDutyRate);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// END: AS923 related stuff
|
||||
//
|
||||
// ================================================================================
|
||||
#endif
|
216
src/lmic/lmic_au921.c
Executable file
216
src/lmic/lmic_au921.c
Executable file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LMIC_DR_LEGACY 0
|
||||
|
||||
#include "lmic_bandplan.h"
|
||||
|
||||
#if defined(CFG_au921)
|
||||
// ================================================================================
|
||||
//
|
||||
// BEG: AU921 related stuff
|
||||
//
|
||||
|
||||
CONST_TABLE(u1_t, _DR2RPS_CRC)[] = {
|
||||
ILLEGAL_RPS, // [-1]
|
||||
MAKERPS(SF12, BW125, CR_4_5, 0, 0), // [0]
|
||||
MAKERPS(SF11, BW125, CR_4_5, 0, 0), // [1]
|
||||
MAKERPS(SF10, BW125, CR_4_5, 0, 0), // [2]
|
||||
MAKERPS(SF9 , BW125, CR_4_5, 0, 0), // [3]
|
||||
MAKERPS(SF8 , BW125, CR_4_5, 0, 0), // [4]
|
||||
MAKERPS(SF7 , BW125, CR_4_5, 0, 0), // [5]
|
||||
MAKERPS(SF8 , BW500, CR_4_5, 0, 0), // [6]
|
||||
ILLEGAL_RPS , // [7]
|
||||
MAKERPS(SF12, BW500, CR_4_5, 0, 0), // [8]
|
||||
MAKERPS(SF11, BW500, CR_4_5, 0, 0), // [9]
|
||||
MAKERPS(SF10, BW500, CR_4_5, 0, 0), // [10]
|
||||
MAKERPS(SF9 , BW500, CR_4_5, 0, 0), // [11]
|
||||
MAKERPS(SF8 , BW500, CR_4_5, 0, 0), // [12]
|
||||
MAKERPS(SF7 , BW500, CR_4_5, 0, 0), // [13]
|
||||
ILLEGAL_RPS
|
||||
};
|
||||
|
||||
static CONST_TABLE(u1_t, maxFrameLens)[] = {
|
||||
59+5, 59+5, 59+5, 123+5, 230+5, 230+5, 230+5, 255,
|
||||
41+5, 117+5, 230+5, 230+5, 230+5, 230+5 };
|
||||
|
||||
uint8_t LMICau921_maxFrameLen(uint8_t dr) {
|
||||
if (dr < LENOF_TABLE(maxFrameLens))
|
||||
return TABLE_GET_U1(maxFrameLens, dr);
|
||||
else
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
static CONST_TABLE(ostime_t, DR2HSYM_osticks)[] = {
|
||||
us2osticksRound(128 << 7), // DR_SF12
|
||||
us2osticksRound(128 << 6), // DR_SF11
|
||||
us2osticksRound(128 << 5), // DR_SF10
|
||||
us2osticksRound(128 << 4), // DR_SF9
|
||||
us2osticksRound(128 << 3), // DR_SF8
|
||||
us2osticksRound(128 << 2), // DR_SF7
|
||||
us2osticksRound(128 << 1), // DR_SF8C
|
||||
us2osticksRound(128 << 0), // ------
|
||||
us2osticksRound(128 << 5), // DR_SF12CR
|
||||
us2osticksRound(128 << 4), // DR_SF11CR
|
||||
us2osticksRound(128 << 3), // DR_SF10CR
|
||||
us2osticksRound(128 << 2), // DR_SF9CR
|
||||
us2osticksRound(128 << 1), // DR_SF8CR
|
||||
us2osticksRound(128 << 0), // DR_SF7CR
|
||||
};
|
||||
|
||||
// get ostime for symbols based on datarate. This is not like us915,
|
||||
// becuase the times don't match between the upper half and lower half
|
||||
// of the table.
|
||||
ostime_t LMICau921_dr2hsym(uint8_t dr) {
|
||||
return TABLE_GET_OSTIME(DR2HSYM_osticks, dr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
u4_t LMICau921_convFreq(xref2cu1_t ptr) {
|
||||
u4_t freq = (os_rlsbf4(ptr - 1) >> 8) * 100;
|
||||
if (freq < AU921_FREQ_MIN || freq > AU921_FREQ_MAX)
|
||||
freq = 0;
|
||||
return freq;
|
||||
}
|
||||
|
||||
// au921: no support for xchannels.
|
||||
bit_t LMIC_setupChannel(u1_t chidx, u4_t freq, u2_t drmap, s1_t band) {
|
||||
return 0; // all channels are hardwired.
|
||||
}
|
||||
|
||||
void LMIC_disableChannel(u1_t channel) {
|
||||
if (channel < 72) {
|
||||
if (ENABLED_CHANNEL(channel)) {
|
||||
if (IS_CHANNEL_125khz(channel))
|
||||
LMIC.activeChannels125khz--;
|
||||
else if (IS_CHANNEL_500khz(channel))
|
||||
LMIC.activeChannels500khz--;
|
||||
}
|
||||
LMIC.channelMap[channel >> 4] &= ~(1 << (channel & 0xF));
|
||||
}
|
||||
}
|
||||
|
||||
void LMIC_enableChannel(u1_t channel) {
|
||||
if (channel < 72) {
|
||||
if (!ENABLED_CHANNEL(channel)) {
|
||||
if (IS_CHANNEL_125khz(channel))
|
||||
LMIC.activeChannels125khz++;
|
||||
else if (IS_CHANNEL_500khz(channel))
|
||||
LMIC.activeChannels500khz++;
|
||||
}
|
||||
LMIC.channelMap[channel >> 4] |= (1 << (channel & 0xF));
|
||||
}
|
||||
}
|
||||
|
||||
void LMIC_enableSubBand(u1_t band) {
|
||||
ASSERT(band < 8);
|
||||
u1_t start = band * 8;
|
||||
u1_t end = start + 8;
|
||||
|
||||
// enable all eight 125 kHz channels in this subband
|
||||
for (int channel = start; channel < end; ++channel)
|
||||
LMIC_enableChannel(channel);
|
||||
|
||||
// there's a single 500 kHz channel associated with
|
||||
// each group of 8 125 kHz channels. Enable it, too.
|
||||
LMIC_enableChannel(64 + band);
|
||||
}
|
||||
void LMIC_disableSubBand(u1_t band) {
|
||||
ASSERT(band < 8);
|
||||
u1_t start = band * 8;
|
||||
u1_t end = start + 8;
|
||||
|
||||
// disable all eight 125 kHz channels in this subband
|
||||
for (int channel = start; channel < end; ++channel)
|
||||
LMIC_disableChannel(channel);
|
||||
|
||||
// there's a single 500 kHz channel associated with
|
||||
// each group of 8 125 kHz channels. Disable it, too.
|
||||
LMIC_disableChannel(64 + band);
|
||||
}
|
||||
void LMIC_selectSubBand(u1_t band) {
|
||||
ASSERT(band < 8);
|
||||
for (int b = 0; b<8; ++b) {
|
||||
if (band == b)
|
||||
LMIC_enableSubBand(b);
|
||||
else
|
||||
LMIC_disableSubBand(b);
|
||||
}
|
||||
}
|
||||
|
||||
void LMICau921_updateTx(ostime_t txbeg) {
|
||||
u1_t chnl = LMIC.txChnl;
|
||||
LMIC.txpow = AU921_TX_EIRP_MAX_DBM;
|
||||
if (chnl < 64) {
|
||||
LMIC.freq = AU921_125kHz_UPFBASE + chnl*AU921_125kHz_UPFSTEP;
|
||||
} else {
|
||||
ASSERT(chnl < 64 + 8);
|
||||
LMIC.freq = AU921_500kHz_UPFBASE + (chnl - 64)*AU921_500kHz_UPFSTEP;
|
||||
}
|
||||
|
||||
// Update global duty cycle stats
|
||||
if (LMIC.globalDutyRate != 0) {
|
||||
ostime_t airtime = calcAirTime(LMIC.rps, LMIC.dataLen);
|
||||
LMIC.globalDutyAvail = txbeg + (airtime << LMIC.globalDutyRate);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
void LMICau921_setBcnRxParams(void) {
|
||||
LMIC.dataLen = 0;
|
||||
LMIC.freq = AU921_500kHz_DNFBASE + LMIC.bcnChnl * AU921_500kHz_DNFSTEP;
|
||||
LMIC.rps = setIh(setNocrc(dndr2rps((dr_t)DR_BCN), 1), LEN_BCN);
|
||||
}
|
||||
#endif // !DISABLE_BEACONS
|
||||
|
||||
// set the Rx1 dndr, rps.
|
||||
void LMICau921_setRx1Params(void) {
|
||||
u1_t const txdr = LMIC.dndr;
|
||||
u1_t candidateDr;
|
||||
LMIC.freq = AU921_500kHz_DNFBASE + (LMIC.txChnl & 0x7) * AU921_500kHz_DNFSTEP;
|
||||
if ( /* TX datarate */txdr < AU921_DR_SF8C)
|
||||
candidateDr = txdr + 8 - LMIC.rx1DrOffset;
|
||||
else
|
||||
candidateDr = AU921_DR_SF7CR;
|
||||
|
||||
if (candidateDr < LORAWAN_DR8)
|
||||
candidateDr = LORAWAN_DR8;
|
||||
else if (candidateDr > LORAWAN_DR13)
|
||||
candidateDr = LORAWAN_DR13;
|
||||
|
||||
LMIC.dndr = candidateDr;
|
||||
LMIC.rps = dndr2rps(LMIC.dndr);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// END: AU921 related stuff
|
||||
//
|
||||
// ================================================================================
|
||||
#endif
|
175
src/lmic/lmic_bandplan.h
Executable file
175
src/lmic/lmic_bandplan.h
Executable file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_bandplan_h_
|
||||
# define _lmic_bandplan_h_
|
||||
|
||||
#ifndef _lmic_h_
|
||||
# include "lmic.h"
|
||||
#endif
|
||||
|
||||
#if defined(CFG_eu868)
|
||||
# include "lmic_bandplan_eu868.h"
|
||||
#elif defined(CFG_us915)
|
||||
# include "lmic_bandplan_us915.h"
|
||||
#elif defined(CFG_au921)
|
||||
# include "lmic_bandplan_au921.h"
|
||||
#elif defined(CFG_as923)
|
||||
# include "lmic_bandplan_as923.h"
|
||||
#elif defined(CFG_in866)
|
||||
# include "lmic_bandplan_in866.h"
|
||||
#else
|
||||
# error "CFG_... not properly set for bandplan"
|
||||
#endif
|
||||
|
||||
// check post-conditions
|
||||
#ifndef DNW2_SAFETY_ZONE
|
||||
# error "DNW2_SAFETY_ZONE not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#ifndef maxFrameLen
|
||||
# error "maxFrameLen() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#ifndef pow2dBm
|
||||
# error "pow2dBm() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#ifndef dr2hsym
|
||||
# error "dr2hsym() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_isValidBeacon1) && !defined(DISABLE_BEACONS)
|
||||
# error "LMICbandplan_isValidBeacon1 not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_isFSK)
|
||||
# error "LMICbandplan_isFSK() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_txDoneFSK)
|
||||
# error "LMICbandplan_txDoneFSK() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_joinAcceptChannelClear)
|
||||
# error "LMICbandplan_joinAcceptChannelClear() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_getInitialDrJoin)
|
||||
# error "LMICbandplan_getInitialDrJoin() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_hasJoinCFlist)
|
||||
# error "LMICbandplan_hasJoinCFlist() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_advanceBeaconChannel)
|
||||
# error "LMICbandplan_advanceBeaconChannel() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_resetDefaultChannels)
|
||||
# error "LMICbandplan_resetDefaultChannels() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_setSessionInitDefaultChannels)
|
||||
# error "LMICbandplan_setSessionInitDefaultChannels() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_setBcnRxParams)
|
||||
# error "LMICbandplan_setBcnRxParams() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_mapChannels)
|
||||
# error "LMICbandplan_mapChannels() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_convFreq)
|
||||
# error "LMICbandplan_convFreq() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_setRx1Params)
|
||||
# error "LMICbandplan_setRx1Params() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_initJoinLoop)
|
||||
# error "LMICbandplan_initJoinLoop() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_nextTx)
|
||||
# error "LMICbandplan_nextTx() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_updateTx)
|
||||
# error "LMICbandplan_updateTx() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_nextJoinState)
|
||||
# error "LMICbandplan_nextJoinState() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_initDefaultChannels)
|
||||
# error "LMICbandplan_initDefaultChannels() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_nextJoinTime)
|
||||
# error "LMICbandplan_nextJoinTime() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
#if !defined(LMICbandplan_init)
|
||||
# error "LMICbandplan_init() not defined by bandplan"
|
||||
#endif
|
||||
//
|
||||
// Things common to lmic.c code
|
||||
//
|
||||
#if !defined(MINRX_SYMS)
|
||||
#define MINRX_SYMS 5
|
||||
#endif // !defined(MINRX_SYMS)
|
||||
#define PAMBL_SYMS 8
|
||||
#define PAMBL_FSK 5
|
||||
#define PRERX_FSK 1
|
||||
#define RXLEN_FSK (1+5+2)
|
||||
|
||||
#define BCN_INTV_osticks sec2osticks(BCN_INTV_sec)
|
||||
#define TXRX_GUARD_osticks ms2osticks(TXRX_GUARD_ms)
|
||||
#define JOIN_GUARD_osticks ms2osticks(JOIN_GUARD_ms)
|
||||
#define DELAY_JACC1_osticks sec2osticks(DELAY_JACC1)
|
||||
#define DELAY_JACC2_osticks sec2osticks(DELAY_JACC2)
|
||||
#define DELAY_EXTDNW2_osticks sec2osticks(DELAY_EXTDNW2)
|
||||
#define BCN_RESERVE_osticks ms2osticks(BCN_RESERVE_ms)
|
||||
#define BCN_GUARD_osticks ms2osticks(BCN_GUARD_ms)
|
||||
#define BCN_WINDOW_osticks ms2osticks(BCN_WINDOW_ms)
|
||||
#define AIRTIME_BCN_osticks us2osticks(AIRTIME_BCN)
|
||||
|
||||
// Special APIs - for development or testing
|
||||
#define isTESTMODE() 0
|
||||
|
||||
// internal APIs
|
||||
ostime_t LMICcore_rndDelay(u1_t secSpan);
|
||||
void LMICcore_setDrJoin(u1_t reason, u1_t dr);
|
||||
|
||||
#endif // _lmic_bandplan_h_
|
115
src/lmic/lmic_bandplan_as923.h
Executable file
115
src/lmic/lmic_bandplan_as923.h
Executable file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_as923_h_
|
||||
# define _lmic_as923_h_
|
||||
|
||||
#ifndef _lmic_eu_like_h_
|
||||
# include "lmic_eu_like.h"
|
||||
#endif
|
||||
|
||||
uint8_t LMICas923_maxFrameLen(uint8_t dr);
|
||||
#define maxFrameLen(dr) LMICas923_maxFrameLen(dr)
|
||||
|
||||
int8_t LMICas923_pow2dBm(uint8_t mcmd_ladr_p1);
|
||||
#define pow2dBm(mcmd_ladr_p1) LMICas923_pow2dBm(mcmd_ladr_p1)
|
||||
|
||||
// Times for half symbol per DR
|
||||
// Per DR table to minimize rounding errors
|
||||
ostime_t LMICas923_dr2hsym(uint8_t dr);
|
||||
#define dr2hsym(dr) LMICas923_dr2hsym(dr)
|
||||
|
||||
static inline int
|
||||
LMICas923_isValidBeacon1(const uint8_t *d) {
|
||||
return os_rlsbf2(&d[OFF_BCN_CRC1]) != os_crc16(d, OFF_BCN_CRC1);
|
||||
}
|
||||
|
||||
#undef LMICbandplan_isValidBeacon1
|
||||
#define LMICbandplan_isValidBeacon1(pFrame) LMICas923_isValidBeacon1(pFrame)
|
||||
|
||||
// override default for LMICbandplan_resetDefaultChannels
|
||||
void
|
||||
LMICas923_resetDefaultChannels(void);
|
||||
|
||||
#undef LMICbandplan_resetDefaultChannels
|
||||
#define LMICbandplan_resetDefaultChannels() \
|
||||
LMICas923_resetDefaultChannels()
|
||||
|
||||
// override default for LMICbandplan_init
|
||||
void LMICas923_init(void);
|
||||
|
||||
#undef LMICbandplan_init
|
||||
#define LMICbandplan_init() \
|
||||
LMICas923_init()
|
||||
|
||||
|
||||
// override default for LMICbandplan_isFSK()
|
||||
#undef LMICbandplan_isFSK
|
||||
#define LMICbandplan_isFSK() (/* TX datarate */LMIC.rxsyms == AS923_DR_FSK)
|
||||
|
||||
// txDone handling for FSK.
|
||||
void
|
||||
LMICas923_txDoneFSK(ostime_t delay, osjobcb_t func);
|
||||
|
||||
#define LMICbandplan_txDoneFsk(delay, func) LMICas923_txDoneFSK(delay, func)
|
||||
|
||||
#define LMICbandplan_getInitialDrJoin() (AS923_DR_SF10)
|
||||
|
||||
void LMICas923_setBcnRxParams(void);
|
||||
#define LMICbandplan_setBcnRxParams() LMICas923_setBcnRxParams()
|
||||
|
||||
u4_t LMICas923_convFreq(xref2cu1_t ptr);
|
||||
#define LMICbandplan_convFreq(ptr) LMICas923_convFreq(ptr)
|
||||
|
||||
void LMICas923_initJoinLoop(void);
|
||||
#define LMICbandplan_initJoinLoop() LMICas923_initJoinLoop()
|
||||
|
||||
// for as923, depending on dwell, we may need to do something else
|
||||
#undef LMICbandplan_setRx1Params
|
||||
void LMICas923_setRx1Params(void);
|
||||
#define LMICbandplan_setRx1Params() LMICas923_setRx1Params()
|
||||
|
||||
ostime_t LMICas923_nextTx(ostime_t now);
|
||||
#define LMICbandplan_nextTx(now) LMICas923_nextTx(now)
|
||||
|
||||
ostime_t LMICas923_nextJoinState(void);
|
||||
#define LMICbandplan_nextJoinState() LMICas923_nextJoinState()
|
||||
|
||||
void LMICas923_initDefaultChannels(bit_t join);
|
||||
#define LMICbandplan_initDefaultChannels(join) LMICas923_initDefaultChannels(join)
|
||||
|
||||
// override default for LMICbandplan_updateTX
|
||||
#undef LMICbandplan_updateTx
|
||||
void LMICas923_updateTx(ostime_t txbeg);
|
||||
#define LMICbandplan_updateTx(txbeg) LMICas923_updateTx(txbeg)
|
||||
|
||||
#undef LMICbandplan_nextJoinTime
|
||||
ostime_t LMICas923_nextJoinTime(ostime_t now);
|
||||
#define LMICbandplan_nextJoinTime(now) LMICas923_nextJoinTime(now)
|
||||
|
||||
#endif // _lmic_as923_h_
|
63
src/lmic/lmic_bandplan_au921.h
Executable file
63
src/lmic/lmic_bandplan_au921.h
Executable file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_au921_h_
|
||||
# define _lmic_au921_h_
|
||||
|
||||
// preconditions for lmic_us_like.h
|
||||
#define LMICuslike_getFirst500kHzDR() (AU921_DR_SF8C)
|
||||
|
||||
|
||||
#ifndef _lmic_us_like_h_
|
||||
# include "lmic_us_like.h"
|
||||
#endif
|
||||
|
||||
uint8_t LMICau921_maxFrameLen(uint8_t dr);
|
||||
#define maxFrameLen(dr) LMICau921_maxFrameLen(dr)
|
||||
|
||||
#define pow2dBm(mcmd_ladr_p1) ((s1_t)(30 - (((mcmd_ladr_p1)&MCMD_LADR_POW_MASK)<<1)))
|
||||
|
||||
ostime_t LMICau921_dr2hsym(uint8_t dr);
|
||||
#define dr2hsym(dr) LMICau921_dr2hsym(dr)
|
||||
|
||||
|
||||
#define LMICbandplan_getInitialDrJoin() (EU868_DR_SF7)
|
||||
|
||||
void LMICau921_setBcnRxParams(void);
|
||||
#define LMICbandplan_setBcnRxParams() LMICau921_setBcnRxParams()
|
||||
|
||||
u4_t LMICau921_convFreq(xref2cu1_t ptr);
|
||||
#define LMICbandplan_convFreq(ptr) LMICau921_convFreq(ptr)
|
||||
|
||||
void LMICau921_setRx1Params(void);
|
||||
#define LMICbandplan_setRx1Params() LMICau921_setRx1Params()
|
||||
|
||||
void LMICau921_updateTx(ostime_t txbeg);
|
||||
#define LMICbandplan_updateTx(txbeg) LMICau921_updateTx(txbeg)
|
||||
|
||||
#endif // _lmic_au921_h_
|
92
src/lmic/lmic_bandplan_eu868.h
Executable file
92
src/lmic/lmic_bandplan_eu868.h
Executable file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_eu868_h_
|
||||
# define _lmic_eu868_h_
|
||||
|
||||
#ifndef _lmic_eu_like_h_
|
||||
# include "lmic_eu_like.h"
|
||||
#endif
|
||||
|
||||
uint8_t LMICeu868_maxFrameLen(uint8_t dr);
|
||||
#define maxFrameLen(dr) LMICeu868_maxFrameLen(dr)
|
||||
|
||||
int8_t LMICeu868_pow2dBm(uint8_t mcmd_ladr_p1);
|
||||
#define pow2dBm(mcmd_ladr_p1) LMICeu868_pow2dBm(mcmd_ladr_p1)
|
||||
|
||||
// Times for half symbol per DR
|
||||
// Per DR table to minimize rounding errors
|
||||
ostime_t LMICeu868_dr2hsym(uint8_t dr);
|
||||
#define dr2hsym(dr) LMICeu868_dr2hsym(dr)
|
||||
|
||||
|
||||
// TODO(tmm@mcci.com) this looks bogus compared to current 1.02 regional
|
||||
// spec. https://github.com/mcci-catena/arduino-lmic/issues/18
|
||||
static inline int
|
||||
LMICeu868_isValidBeacon1(const uint8_t *d) {
|
||||
return d[OFF_BCN_CRC1] != (u1_t)os_crc16(d, OFF_BCN_CRC1);
|
||||
}
|
||||
|
||||
#undef LMICbandplan_isValidBeacon1
|
||||
#define LMICbandplan_isValidBeacon1(pFrame) LMICeu868_isValidBeacon1(pFrame)
|
||||
|
||||
// override default for LMICbandplan_isFSK()
|
||||
#undef LMICbandplan_isFSK
|
||||
#define LMICbandplan_isFSK() (/* TX datarate */LMIC.rxsyms == EU868_DR_FSK)
|
||||
|
||||
// txDone handling for FSK.
|
||||
void
|
||||
LMICeu868_txDoneFSK(ostime_t delay, osjobcb_t func);
|
||||
|
||||
#define LMICbandplan_txDoneFsk(delay, func) LMICeu868_txDoneFSK(delay, func)
|
||||
|
||||
#define LMICbandplan_getInitialDrJoin() (EU868_DR_SF7)
|
||||
|
||||
void LMICeu868_setBcnRxParams(void);
|
||||
#define LMICbandplan_setBcnRxParams() LMICeu868_setBcnRxParams()
|
||||
|
||||
u4_t LMICeu868_convFreq(xref2cu1_t ptr);
|
||||
#define LMICbandplan_convFreq(ptr) LMICeu868_convFreq(ptr)
|
||||
|
||||
void LMICeu868_initJoinLoop(void);
|
||||
#define LMICbandplan_initJoinLoop() LMICeu868_initJoinLoop()
|
||||
|
||||
ostime_t LMICeu868_nextTx(ostime_t now);
|
||||
#define LMICbandplan_nextTx(now) LMICeu868_nextTx(now)
|
||||
|
||||
ostime_t LMICeu868_nextJoinState(void);
|
||||
#define LMICbandplan_nextJoinState() LMICeu868_nextJoinState()
|
||||
|
||||
void LMICeu868_initDefaultChannels(bit_t join);
|
||||
#define LMICbandplan_initDefaultChannels(join) LMICeu868_initDefaultChannels(join)
|
||||
|
||||
#undef LMICbandplan_nextJoinTime
|
||||
ostime_t LMICeu868_nextJoinTime(ostime_t now);
|
||||
#define LMICbandplan_nextJoinTime(now) LMICeu868_nextJoinTime(now)
|
||||
|
||||
#endif // _lmic_eu868_h_
|
85
src/lmic/lmic_bandplan_in866.h
Executable file
85
src/lmic/lmic_bandplan_in866.h
Executable file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_in866_h_
|
||||
# define _lmic_in866_h_
|
||||
|
||||
#ifndef _lmic_eu_like_h_
|
||||
# include "lmic_eu_like.h"
|
||||
#endif
|
||||
|
||||
uint8_t LMICin866_maxFrameLen(uint8_t dr);
|
||||
#define maxFrameLen(dr) LMICin866_maxFrameLen(dr)
|
||||
|
||||
int8_t LMICin866_pow2dBm(uint8_t mcmd_ladr_p1);
|
||||
#define pow2dBm(mcmd_ladr_p1) LMICin866_pow2dBm(mcmd_ladr_p1)
|
||||
|
||||
// Times for half symbol per DR
|
||||
// Per DR table to minimize rounding errors
|
||||
ostime_t LMICin866_dr2hsym(uint8_t dr);
|
||||
#define dr2hsym(dr) LMICin866_dr2hsym(dr)
|
||||
|
||||
static inline int
|
||||
LMICin866_isValidBeacon1(const uint8_t *d) {
|
||||
return os_rlsbf2(&d[OFF_BCN_CRC1]) != os_crc16(d, OFF_BCN_CRC1);
|
||||
}
|
||||
|
||||
#undef LMICbandplan_isValidBeacon1
|
||||
#define LMICbandplan_isValidBeacon1(pFrame) LMICin866_isValidBeacon1(pFrame)
|
||||
|
||||
// override default for LMICbandplan_isFSK()
|
||||
#undef LMICbandplan_isFSK
|
||||
#define LMICbandplan_isFSK() (/* TX datarate */LMIC.rxsyms == IN866_DR_FSK)
|
||||
|
||||
// txDone handling for FSK.
|
||||
void
|
||||
LMICin866_txDoneFSK(ostime_t delay, osjobcb_t func);
|
||||
|
||||
#define LMICbandplan_txDoneFsk(delay, func) LMICin866_txDoneFSK(delay, func)
|
||||
|
||||
#define LMICbandplan_getInitialDrJoin() (IN866_DR_SF7)
|
||||
|
||||
void LMICin866_setBcnRxParams(void);
|
||||
#define LMICbandplan_setBcnRxParams() LMICin866_setBcnRxParams()
|
||||
|
||||
u4_t LMICin866_convFreq(xref2cu1_t ptr);
|
||||
#define LMICbandplan_convFreq(ptr) LMICin866_convFreq(ptr)
|
||||
|
||||
void LMICin866_initJoinLoop(void);
|
||||
#define LMICbandplan_initJoinLoop() LMICin866_initJoinLoop()
|
||||
|
||||
ostime_t LMICin866_nextTx(ostime_t now);
|
||||
#define LMICbandplan_nextTx(now) LMICin866_nextTx(now)
|
||||
|
||||
ostime_t LMICin866_nextJoinState(void);
|
||||
#define LMICbandplan_nextJoinState() LMICin866_nextJoinState()
|
||||
|
||||
void LMICin866_initDefaultChannels(bit_t join);
|
||||
#define LMICbandplan_initDefaultChannels(join) LMICin866_initDefaultChannels(join)
|
||||
|
||||
#endif // _lmic_in866_h_
|
62
src/lmic/lmic_bandplan_us915.h
Executable file
62
src/lmic/lmic_bandplan_us915.h
Executable file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_us915_h_
|
||||
# define _lmic_us915_h_
|
||||
|
||||
// preconditions for lmic_us_like.h
|
||||
#define LMICuslike_getFirst500kHzDR() (US915_DR_SF8C)
|
||||
|
||||
#ifndef _lmic_us_like_h_
|
||||
# include "lmic_us_like.h"
|
||||
#endif
|
||||
|
||||
uint8_t LMICus915_maxFrameLen(uint8_t dr);
|
||||
#define maxFrameLen(dr) LMICus915_maxFrameLen(dr)
|
||||
|
||||
#define pow2dBm(mcmd_ladr_p1) ((s1_t)(US915_TX_MAX_DBM - (((mcmd_ladr_p1)&MCMD_LADR_POW_MASK)<<1)))
|
||||
|
||||
ostime_t LMICus915_dr2hsym(uint8_t dr);
|
||||
#define dr2hsym(dr) LMICus915_dr2hsym(dr)
|
||||
|
||||
|
||||
#define LMICbandplan_getInitialDrJoin() (US915_DR_SF7)
|
||||
|
||||
void LMICus915_setBcnRxParams(void);
|
||||
#define LMICbandplan_setBcnRxParams() LMICus915_setBcnRxParams()
|
||||
|
||||
u4_t LMICus915_convFreq(xref2cu1_t ptr);
|
||||
#define LMICbandplan_convFreq(ptr) LMICus915_convFreq(ptr)
|
||||
|
||||
void LMICus915_setRx1Params(void);
|
||||
#define LMICbandplan_setRx1Params() LMICus915_setRx1Params()
|
||||
|
||||
void LMICus915_updateTx(ostime_t txbeg);
|
||||
#define LMICbandplan_updateTx(txbeg) LMICus915_updateTx(txbeg)
|
||||
|
||||
#endif // _lmic_us915_h_
|
181
src/lmic/lmic_config_preconditions.h
Executable file
181
src/lmic/lmic_config_preconditions.h
Executable file
@ -0,0 +1,181 @@
|
||||
/* lmic_config_preconditions.h Fri May 19 2017 23:58:34 tmm */
|
||||
|
||||
/*
|
||||
|
||||
Module: lmic_config_preconditions.h
|
||||
|
||||
Function:
|
||||
Preconditions for LMIC configuration.
|
||||
|
||||
Version:
|
||||
V2.0.0 Sun Aug 06 2017 17:40:44 tmm Edit level 1
|
||||
|
||||
Copyright notice:
|
||||
This file copyright (C) 2017 by
|
||||
|
||||
MCCI Corporation
|
||||
3520 Krums Corners Road
|
||||
Ithaca, NY 14850
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Author:
|
||||
Terry Moore, MCCI Corporation July 2017
|
||||
|
||||
Revision history:
|
||||
2.0.0 Sun Aug 06 2017 17:40:44 tmm
|
||||
Module created.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _LMIC_CONFIG_PRECONDITIONS_H_
|
||||
# define _LMIC_CONFIG_PRECONDITIONS_H_
|
||||
|
||||
// We need to be able to compile with different options without editing source.
|
||||
// When building with a more advanced environment, set the following variable:
|
||||
// ARDUINO_LMIC_PROJECT_CONFIG_H=my_project_config.h
|
||||
//
|
||||
// otherwise the lmic_project_config.h from the ../../project_config directory will be used.
|
||||
#ifndef ARDUINO_LMIC_PROJECT_CONFIG_H
|
||||
# define ARDUINO_LMIC_PROJECT_CONFIG_H ../esp_idf_lmic_config.h
|
||||
#endif
|
||||
|
||||
#define CFG_TEXT_1(x) CFG_TEXT_2(x)
|
||||
#define CFG_TEXT_2(x) #x
|
||||
|
||||
// constants for comparison
|
||||
#define LMIC_REGION_eu868 1
|
||||
#define LMIC_REGION_us915 2
|
||||
#define LMIC_REGION_cn783 3
|
||||
#define LMIC_REGION_eu433 4
|
||||
#define LMIC_REGION_au921 5
|
||||
#define LMIC_REGION_cn490 6
|
||||
#define LMIC_REGION_as923 7
|
||||
#define LMIC_REGION_kr921 8
|
||||
#define LMIC_REGION_in866 9
|
||||
|
||||
// Some regions have country-specific overrides. For generality, we specify
|
||||
// country codes using the LMIC_COUNTY_CODE_C() macro These values are chosen
|
||||
// from the 2-letter domain suffixes standardized by ISO-3166-1 alpha2 (see
|
||||
// https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). They are therefore
|
||||
// 16-bit constants. By convention, we use UPPER-CASE letters, thus
|
||||
// LMIC_COUNTRY_CODE('J', 'P'), not ('j', 'p').
|
||||
#define LMIC_COUNTRY_CODE_C(c1, c2) ((c1) * 256 + (c2))
|
||||
|
||||
// this special code means "no country code defined"
|
||||
#define LMIC_COUNTRY_CODE_NONE 0
|
||||
|
||||
// specific countries. Only the ones that are needed by the code are defined.
|
||||
#define LMIC_COUNTRY_CODE_JP LMIC_COUNTRY_CODE_C('J', 'P')
|
||||
|
||||
// include the file that the user is really supposed to edit. But for really strange
|
||||
// ports, this can be suppressed
|
||||
#ifndef ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS
|
||||
# include CFG_TEXT_1(ARDUINO_LMIC_PROJECT_CONFIG_H)
|
||||
#endif /* ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS */
|
||||
|
||||
// a mask of the supported regions
|
||||
// TODO(tmm@mcci.com) consider moving this block to a central file as it's not
|
||||
// user-editable.
|
||||
#define LMIC_REGIONS_SUPPORTED ( \
|
||||
(1 << LMIC_REGION_eu868) | \
|
||||
(1 << LMIC_REGION_us915) | \
|
||||
/* (1 << LMIC_REGION_cn783) | */ \
|
||||
/* (1 << LMIC_REGION_eu433) | */ \
|
||||
(1 << LMIC_REGION_au921) | \
|
||||
/* (1 << LMIC_REGION_cn490) | */ \
|
||||
(1 << LMIC_REGION_as923) | \
|
||||
/* (1 << LMIC_REGION_kr921) | */ \
|
||||
(1 << LMIC_REGION_in866) | \
|
||||
0)
|
||||
|
||||
//
|
||||
// Our input is a -D of one of CFG_eu868, CFG_us915, CFG_as923, CFG_au915, CFG_in866
|
||||
// More will be added in the the future. So at this point we create CFG_region with
|
||||
// following values. These are in order of the sections in the manual. Not all of the
|
||||
// below are supported yet.
|
||||
//
|
||||
# define CFG_LMIC_REGION_MASK \
|
||||
((defined(CFG_eu868) << LMIC_REGION_eu868) | \
|
||||
(defined(CFG_us915) << LMIC_REGION_us915) | \
|
||||
(defined(CFG_cn783) << LMIC_REGION_cn783) | \
|
||||
(defined(CFG_eu433) << LMIC_REGION_eu433) | \
|
||||
(defined(CFG_au921) << LMIC_REGION_au921) | \
|
||||
(defined(CFG_cn490) << LMIC_REGION_cn490) | \
|
||||
(defined(CFG_as923) << LMIC_REGION_as923) | \
|
||||
(defined(CFG_kr921) << LMIC_REGION_kr921) | \
|
||||
(defined(CFG_in866) << LMIC_REGION_in866) | \
|
||||
0)
|
||||
|
||||
// the selected region.
|
||||
#if defined(CFG_eu868)
|
||||
# define CFG_region LMIC_REGION_eu868
|
||||
#elif defined(CFG_us915)
|
||||
# define CFG_region LMIC_REGION_us915
|
||||
#elif defined(CFG_cn783)
|
||||
# define CFG_region LMIC_REGION_cn783
|
||||
#elif defined(CFG_eu433)
|
||||
# define CFG_region LMIC_REGION_eu433
|
||||
#elif defined(CFG_au921)
|
||||
# define CFG_region LMIC_REGION_au921
|
||||
#elif defined(CFG_cn490)
|
||||
# define CFG_region LMIC_REGION_cn490
|
||||
#elif defined(CFG_as923)
|
||||
# define CFG_region LMIC_REGION_as923
|
||||
#elif defined(CFG_kr921)
|
||||
# define CFG_region LMIC_REGION_kr921
|
||||
#elif defined(CFG_in866)
|
||||
# define CFG_region LMIC_REGION_in866
|
||||
#else
|
||||
# define CFG_region 0
|
||||
#endif
|
||||
|
||||
// finally the mask of` US-like and EU-like regions
|
||||
#define CFG_LMIC_EU_like_MASK ( \
|
||||
(1 << LMIC_REGION_eu868) | \
|
||||
/* (1 << LMIC_REGION_us915) | */ \
|
||||
(1 << LMIC_REGION_cn783) | \
|
||||
(1 << LMIC_REGION_eu433) | \
|
||||
/* (1 << LMIC_REGION_au921) | */ \
|
||||
/* (1 << LMIC_REGION_cn490) | */ \
|
||||
(1 << LMIC_REGION_as923) | \
|
||||
(1 << LMIC_REGION_kr921) | \
|
||||
(1 << LMIC_REGION_in866) | \
|
||||
0)
|
||||
|
||||
#define CFG_LMIC_US_like_MASK ( \
|
||||
/* (1 << LMIC_REGION_eu868) | */ \
|
||||
(1 << LMIC_REGION_us915) | \
|
||||
/* (1 << LMIC_REGION_cn783) | */ \
|
||||
/* (1 << LMIC_REGION_eu433) | */ \
|
||||
(1 << LMIC_REGION_au921) | \
|
||||
/* (1 << LMIC_REGION_cn490) | */ \
|
||||
/* (1 << LMIC_REGION_as923) | */ \
|
||||
/* (1 << LMIC_REGION_kr921) | */ \
|
||||
/* (1 << LMIC_REGION_in866) | */ \
|
||||
0)
|
||||
|
||||
#define CFG_LMIC_EU_like (!!(CFG_LMIC_REGION_MASK & CFG_LMIC_EU_like_MASK))
|
||||
#define CFG_LMIC_US_like (!!(CFG_LMIC_REGION_MASK & CFG_LMIC_US_like_MASK))
|
||||
|
||||
|
||||
|
||||
#endif /* _LMIC_CONFIG_PRECONDITIONS_H_ */
|
233
src/lmic/lmic_eu868.c
Executable file
233
src/lmic/lmic_eu868.c
Executable file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LMIC_DR_LEGACY 0
|
||||
|
||||
#include "lmic_bandplan.h"
|
||||
|
||||
#if defined(CFG_eu868)
|
||||
// ================================================================================
|
||||
//
|
||||
// BEG: EU868 related stuff
|
||||
//
|
||||
|
||||
CONST_TABLE(u1_t, _DR2RPS_CRC)[] = {
|
||||
ILLEGAL_RPS,
|
||||
(u1_t)MAKERPS(SF12, BW125, CR_4_5, 0, 0),
|
||||
(u1_t)MAKERPS(SF11, BW125, CR_4_5, 0, 0),
|
||||
(u1_t)MAKERPS(SF10, BW125, CR_4_5, 0, 0),
|
||||
(u1_t)MAKERPS(SF9, BW125, CR_4_5, 0, 0),
|
||||
(u1_t)MAKERPS(SF8, BW125, CR_4_5, 0, 0),
|
||||
(u1_t)MAKERPS(SF7, BW125, CR_4_5, 0, 0),
|
||||
(u1_t)MAKERPS(SF7, BW250, CR_4_5, 0, 0),
|
||||
(u1_t)MAKERPS(FSK, BW125, CR_4_5, 0, 0),
|
||||
ILLEGAL_RPS
|
||||
};
|
||||
|
||||
static CONST_TABLE(u1_t, maxFrameLens)[] = { 64,64,64,123 };
|
||||
|
||||
uint8_t LMICeu868_maxFrameLen(uint8_t dr) {
|
||||
if (dr < LENOF_TABLE(maxFrameLens))
|
||||
return TABLE_GET_U1(maxFrameLens, dr);
|
||||
else
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
static CONST_TABLE(s1_t, TXPOWLEVELS)[] = {
|
||||
20, 14, 11, 8, 5, 2, 0,0, 0,0,0,0, 0,0,0,0
|
||||
};
|
||||
|
||||
int8_t LMICeu868_pow2dBm(uint8_t mcmd_ladr_p1) {
|
||||
return TABLE_GET_S1(TXPOWLEVELS, (mcmd_ladr_p1&MCMD_LADR_POW_MASK)>>MCMD_LADR_POW_SHIFT);
|
||||
}
|
||||
|
||||
// only used in this module, but used by variant macro dr2hsym().
|
||||
static CONST_TABLE(ostime_t, DR2HSYM_osticks)[] = {
|
||||
us2osticksRound(128 << 7), // DR_SF12
|
||||
us2osticksRound(128 << 6), // DR_SF11
|
||||
us2osticksRound(128 << 5), // DR_SF10
|
||||
us2osticksRound(128 << 4), // DR_SF9
|
||||
us2osticksRound(128 << 3), // DR_SF8
|
||||
us2osticksRound(128 << 2), // DR_SF7
|
||||
us2osticksRound(128 << 1), // DR_SF7B
|
||||
us2osticksRound(80) // FSK -- not used (time for 1/2 byte)
|
||||
};
|
||||
|
||||
ostime_t LMICeu868_dr2hsym(uint8_t dr) {
|
||||
return TABLE_GET_OSTIME(DR2HSYM_osticks, dr);
|
||||
}
|
||||
|
||||
|
||||
enum { NUM_DEFAULT_CHANNELS = 3 };
|
||||
static CONST_TABLE(u4_t, iniChannelFreq)[6] = {
|
||||
// Join frequencies and duty cycle limit (0.1%)
|
||||
EU868_F1 | BAND_MILLI, EU868_F2 | BAND_MILLI, EU868_F3 | BAND_MILLI,
|
||||
// Default operational frequencies and duty cycle limit (1%)
|
||||
EU868_F1 | BAND_CENTI, EU868_F2 | BAND_CENTI, EU868_F3 | BAND_CENTI,
|
||||
};
|
||||
|
||||
void LMICeu868_initDefaultChannels(bit_t join) {
|
||||
os_clearMem(&LMIC.channelFreq, sizeof(LMIC.channelFreq));
|
||||
os_clearMem(&LMIC.channelDrMap, sizeof(LMIC.channelDrMap));
|
||||
os_clearMem(&LMIC.bands, sizeof(LMIC.bands));
|
||||
|
||||
LMIC.channelMap = (1 << NUM_DEFAULT_CHANNELS) - 1;
|
||||
u1_t su = join ? 0 : NUM_DEFAULT_CHANNELS;
|
||||
for (u1_t fu = 0; fu<NUM_DEFAULT_CHANNELS; fu++, su++) {
|
||||
LMIC.channelFreq[fu] = TABLE_GET_U4(iniChannelFreq, su);
|
||||
// TODO(tmm@mcci.com): don't use EU DR directly, use something from the LMIC context or a static const
|
||||
LMIC.channelDrMap[fu] = DR_RANGE_MAP(EU868_DR_SF12, EU868_DR_SF7);
|
||||
}
|
||||
|
||||
LMIC.bands[BAND_MILLI].txcap = 1000; // 0.1%
|
||||
LMIC.bands[BAND_MILLI].txpow = 14;
|
||||
LMIC.bands[BAND_MILLI].lastchnl = os_getRndU1() % MAX_CHANNELS;
|
||||
LMIC.bands[BAND_CENTI].txcap = 100; // 1%
|
||||
LMIC.bands[BAND_CENTI].txpow = 14;
|
||||
LMIC.bands[BAND_CENTI].lastchnl = os_getRndU1() % MAX_CHANNELS;
|
||||
LMIC.bands[BAND_DECI].txcap = 10; // 10%
|
||||
LMIC.bands[BAND_DECI].txpow = 27;
|
||||
LMIC.bands[BAND_DECI].lastchnl = os_getRndU1() % MAX_CHANNELS;
|
||||
LMIC.bands[BAND_MILLI].avail =
|
||||
LMIC.bands[BAND_CENTI].avail =
|
||||
LMIC.bands[BAND_DECI].avail = os_getTime();
|
||||
}
|
||||
|
||||
bit_t LMIC_setupBand(u1_t bandidx, s1_t txpow, u2_t txcap) {
|
||||
if (bandidx > BAND_AUX) return 0;
|
||||
//band_t* b = &LMIC.bands[bandidx];
|
||||
xref2band_t b = &LMIC.bands[bandidx];
|
||||
b->txpow = txpow;
|
||||
b->txcap = txcap;
|
||||
b->avail = os_getTime();
|
||||
b->lastchnl = os_getRndU1() % MAX_CHANNELS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bit_t LMIC_setupChannel(u1_t chidx, u4_t freq, u2_t drmap, s1_t band) {
|
||||
if (chidx >= MAX_CHANNELS)
|
||||
return 0;
|
||||
if (band == -1) {
|
||||
if (freq >= 869400000 && freq <= 869650000)
|
||||
freq |= BAND_DECI; // 10% 27dBm
|
||||
else if ((freq >= 868000000 && freq <= 868600000) ||
|
||||
(freq >= 869700000 && freq <= 870000000))
|
||||
freq |= BAND_CENTI; // 1% 14dBm
|
||||
else
|
||||
freq |= BAND_MILLI; // 0.1% 14dBm
|
||||
}
|
||||
else {
|
||||
if (band > BAND_AUX) return 0;
|
||||
freq = (freq&~3) | band;
|
||||
}
|
||||
LMIC.channelFreq[chidx] = freq;
|
||||
// TODO(tmm@mcci.com): don't use US SF directly, use something from the LMIC context or a static const
|
||||
LMIC.channelDrMap[chidx] = drmap == 0 ? DR_RANGE_MAP(EU868_DR_SF12, EU868_DR_SF7) : drmap;
|
||||
LMIC.channelMap |= 1 << chidx; // enabled right away
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u4_t LMICeu868_convFreq(xref2cu1_t ptr) {
|
||||
u4_t freq = (os_rlsbf4(ptr - 1) >> 8) * 100;
|
||||
if (freq < EU868_FREQ_MIN || freq > EU868_FREQ_MAX)
|
||||
freq = 0;
|
||||
return freq;
|
||||
}
|
||||
|
||||
ostime_t LMICeu868_nextJoinTime(ostime_t time) {
|
||||
// is the avail time in the future?
|
||||
if ((s4_t) (time - LMIC.bands[BAND_MILLI].avail) < 0)
|
||||
// yes: then wait until then.
|
||||
time = LMIC.bands[BAND_MILLI].avail;
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
ostime_t LMICeu868_nextTx(ostime_t now) {
|
||||
u1_t bmap = 0xF;
|
||||
do {
|
||||
ostime_t mintime = now + /*8h*/sec2osticks(28800);
|
||||
u1_t band = 0;
|
||||
for (u1_t bi = 0; bi<4; bi++) {
|
||||
if ((bmap & (1 << bi)) && mintime - LMIC.bands[bi].avail > 0)
|
||||
mintime = LMIC.bands[band = bi].avail;
|
||||
}
|
||||
// Find next channel in given band
|
||||
u1_t chnl = LMIC.bands[band].lastchnl;
|
||||
for (u1_t ci = 0; ci<MAX_CHANNELS; ci++) {
|
||||
if ((chnl = (chnl + 1)) >= MAX_CHANNELS)
|
||||
chnl -= MAX_CHANNELS;
|
||||
if ((LMIC.channelMap & (1 << chnl)) != 0 && // channel enabled
|
||||
(LMIC.channelDrMap[chnl] & (1 << (LMIC.datarate & 0xF))) != 0 &&
|
||||
band == (LMIC.channelFreq[chnl] & 0x3)) { // in selected band
|
||||
LMIC.txChnl = LMIC.bands[band].lastchnl = chnl;
|
||||
return mintime;
|
||||
}
|
||||
}
|
||||
if ((bmap &= ~(1 << band)) == 0) {
|
||||
// No feasible channel found!
|
||||
return mintime;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
void LMICeu868_setBcnRxParams(void) {
|
||||
LMIC.dataLen = 0;
|
||||
LMIC.freq = LMIC.channelFreq[LMIC.bcnChnl] & ~(u4_t)3;
|
||||
LMIC.rps = setIh(setNocrc(dndr2rps((dr_t)DR_BCN), 1), LEN_BCN);
|
||||
}
|
||||
#endif // !DISABLE_BEACONS
|
||||
|
||||
#if !defined(DISABLE_JOIN)
|
||||
ostime_t LMICeu868_nextJoinState(void) {
|
||||
return LMICeulike_nextJoinState(NUM_DEFAULT_CHANNELS);
|
||||
}
|
||||
#endif // !DISABLE_JOIN
|
||||
|
||||
// txDone handling for FSK.
|
||||
void
|
||||
LMICeu868_txDoneFSK(ostime_t delay, osjobcb_t func) {
|
||||
LMIC.rxtime = LMIC.txend + delay - PRERX_FSK*us2osticksRound(160);
|
||||
LMIC.rxsyms = RXLEN_FSK;
|
||||
os_setTimedCallback(&LMIC.osjob, LMIC.rxtime - RX_RAMPUP, func);
|
||||
}
|
||||
|
||||
void
|
||||
LMICeu868_initJoinLoop(void) {
|
||||
LMICeulike_initJoinLoop(NUM_DEFAULT_CHANNELS, /* adr dBm */ EU868_TX_EIRP_MAX_DBM);
|
||||
}
|
||||
|
||||
//
|
||||
// END: EU868 related stuff
|
||||
//
|
||||
// ================================================================================
|
||||
#endif
|
159
src/lmic/lmic_eu_like.c
Executable file
159
src/lmic/lmic_eu_like.c
Executable file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LMIC_DR_LEGACY 0
|
||||
|
||||
#include "lmic_bandplan.h"
|
||||
|
||||
#if CFG_LMIC_EU_like
|
||||
|
||||
void LMIC_enableSubBand(u1_t band) {
|
||||
}
|
||||
|
||||
void LMIC_disableSubBand(u1_t band) {
|
||||
}
|
||||
|
||||
void LMIC_disableChannel(u1_t channel) {
|
||||
LMIC.channelFreq[channel] = 0;
|
||||
LMIC.channelDrMap[channel] = 0;
|
||||
LMIC.channelMap &= ~(1 << channel);
|
||||
}
|
||||
|
||||
// this is a no-op provided for compatibilty
|
||||
void LMIC_enableChannel(u1_t channel) {
|
||||
}
|
||||
|
||||
u1_t LMICeulike_mapChannels(u1_t chpage, u2_t chmap) {
|
||||
// Bad page, disable all channel, enable non-existent
|
||||
if (chpage != 0 || chmap == 0 || (chmap & ~LMIC.channelMap) != 0)
|
||||
return 0; // illegal input
|
||||
for (u1_t chnl = 0; chnl<MAX_CHANNELS; chnl++) {
|
||||
if ((chmap & (1 << chnl)) != 0 && LMIC.channelFreq[chnl] == 0)
|
||||
chmap &= ~(1 << chnl); // ignore - channel is not defined
|
||||
}
|
||||
LMIC.channelMap = chmap;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if !defined(DISABLE_JOIN)
|
||||
void LMICeulike_initJoinLoop(uint8_t nDefaultChannels, s1_t adrTxPow) {
|
||||
#if CFG_TxContinuousMode
|
||||
LMIC.txChnl = 0
|
||||
#else
|
||||
LMIC.txChnl = os_getRndU1() % nDefaultChannels;
|
||||
#endif
|
||||
LMIC.adrTxPow = adrTxPow;
|
||||
// TODO(tmm@mcci.com) don't use EU directly, use a table. That
|
||||
// will allow support for EU-style bandplans with similar code.
|
||||
LMICcore_setDrJoin(DRCHG_SET, LMICbandplan_getInitialDrJoin());
|
||||
LMICbandplan_initDefaultChannels(/* put into join mode */ 1);
|
||||
ASSERT((LMIC.opmode & OP_NEXTCHNL) == 0);
|
||||
LMIC.txend = os_getTime() + LMICcore_rndDelay(8);
|
||||
}
|
||||
#endif // DISABLE_JOIN
|
||||
|
||||
void LMICeulike_updateTx(ostime_t txbeg) {
|
||||
u4_t freq = LMIC.channelFreq[LMIC.txChnl];
|
||||
// Update global/band specific duty cycle stats
|
||||
ostime_t airtime = calcAirTime(LMIC.rps, LMIC.dataLen);
|
||||
// Update channel/global duty cycle stats
|
||||
xref2band_t band = &LMIC.bands[freq & 0x3];
|
||||
LMIC.freq = freq & ~(u4_t)3;
|
||||
LMIC.txpow = band->txpow;
|
||||
band->avail = txbeg + airtime * band->txcap;
|
||||
if (LMIC.globalDutyRate != 0)
|
||||
LMIC.globalDutyAvail = txbeg + (airtime << LMIC.globalDutyRate);
|
||||
}
|
||||
|
||||
#if !defined(DISABLE_JOIN)
|
||||
//
|
||||
// TODO(tmm@mcci.com):
|
||||
//
|
||||
// The definition of this is a little strange. this seems to return a time, but
|
||||
// in reality it returns 0 if the caller should continue scanning through
|
||||
// channels, and 1 if the caller has scanned all channels on this session,
|
||||
// and therefore should reset to the beginning. The IBM 1.6 code is the
|
||||
// same way, so apparently I just carried this across. We should declare
|
||||
// as bool_t and change callers to use the result clearly as a flag.
|
||||
//
|
||||
ostime_t LMICeulike_nextJoinState(uint8_t nDefaultChannels) {
|
||||
u1_t failed = 0;
|
||||
|
||||
// Try each default channel with same DR
|
||||
// If all fail try next lower datarate
|
||||
if (++LMIC.txChnl == /* NUM_DEFAULT_CHANNELS */ nDefaultChannels)
|
||||
LMIC.txChnl = 0;
|
||||
if ((++LMIC.txCnt % nDefaultChannels) == 0) {
|
||||
// Lower DR every nth try (having all default channels with same DR)
|
||||
//
|
||||
// TODO(tmm@mcci.com) add new DR_REGIN_JOIN_MIN instead of LORAWAN_DR0;
|
||||
// then we can eliminate the LMIC_REGION_as923 below because we'll set
|
||||
// the failed flag here. This will cause the outer caller to take the
|
||||
// appropriate join path. Or add new LMICeulike_GetLowestJoinDR()
|
||||
//
|
||||
if (LMIC.datarate == LORAWAN_DR0)
|
||||
failed = 1; // we have tried all DR - signal EV_JOIN_FAILED
|
||||
else
|
||||
{
|
||||
// TODO(tmm@mcci.com) - see above; please remove regional dependency from this file.
|
||||
#if CFG_region != LMIC_REGION_as923
|
||||
LMICcore_setDrJoin(DRCHG_NOJACC, decDR((dr_t)LMIC.datarate));
|
||||
#else
|
||||
// in the join of AS923 v1.1 or older, only DR2 is used.
|
||||
// no need to change the DR.
|
||||
LMIC.datarate = AS923_DR_SF10;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// Clear NEXTCHNL because join state engine controls channel hopping
|
||||
LMIC.opmode &= ~OP_NEXTCHNL;
|
||||
// Move txend to randomize synchronized concurrent joins.
|
||||
// Duty cycle is based on txend.
|
||||
ostime_t const time = LMICbandplan_nextJoinTime(os_getTime());
|
||||
|
||||
// TODO(tmm@mcci.com): change delay to (0:1) secs + a known t0, but randomized;
|
||||
// starting adding a bias after 1 hour, 25 hours, etc.; and limit the duty
|
||||
// cycle on power up. For testability, add a way to set the join start time
|
||||
// externally (a test API) so we can check this feature.
|
||||
// See https://github.com/mcci-catena/arduino-lmic/issues/2
|
||||
// Current code doesn't match LoRaWAN 1.0.2 requirements.
|
||||
|
||||
LMIC.txend = time +
|
||||
(isTESTMODE()
|
||||
// Avoid collision with JOIN ACCEPT @ SF12 being sent by GW (but we missed it)
|
||||
? DNW2_SAFETY_ZONE
|
||||
// Otherwise: randomize join (street lamp case):
|
||||
// SF12:255, SF11:127, .., SF7:8secs
|
||||
//
|
||||
: DNW2_SAFETY_ZONE + LMICcore_rndDelay(255 >> LMIC.datarate));
|
||||
// 1 - triggers EV_JOIN_FAILED event
|
||||
return failed;
|
||||
}
|
||||
#endif // !DISABLE_JOIN
|
||||
|
||||
#endif // CFG_LMIC_EU_like
|
98
src/lmic/lmic_eu_like.h
Executable file
98
src/lmic/lmic_eu_like.h
Executable file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_eu_like_h_
|
||||
# define _lmic_eu_like_h_
|
||||
|
||||
#ifndef _lmic_h_
|
||||
# include "lmic.h"
|
||||
#endif
|
||||
|
||||
// make sure we want US-like code
|
||||
#if !CFG_LMIC_EU_like
|
||||
# error "lmic not configured for EU-like bandplan"
|
||||
#endif
|
||||
|
||||
// TODO(tmm@mcci.com): this should come from the lmic.h or lorabase.h file; and
|
||||
// it's probably affected by the fix to this issue:
|
||||
// https://github.com/mcci-catena/arduino-lmic/issues/2
|
||||
#define DNW2_SAFETY_ZONE ms2osticks(3000)
|
||||
|
||||
// provide a default for LMICbandplan_isValidBeacon1()
|
||||
static inline int
|
||||
LMICeulike_isValidBeacon1(const uint8_t *d) {
|
||||
return os_rlsbf2(&d[OFF_BCN_CRC1]) != os_crc16(d, OFF_BCN_CRC1);
|
||||
}
|
||||
|
||||
#define LMICbandplan_isValidBeacon1(pFrame) LMICeulike_isValidBeacon1(pFrame)
|
||||
|
||||
|
||||
// provide a default for LMICbandplan_isFSK()
|
||||
#define LMICbandplan_isFSK() (0)
|
||||
|
||||
// provide a default LMICbandplan_txDoneDoFSK()
|
||||
#define LMICbandplan_txDoneFSK(delay, func) do { } while (0)
|
||||
|
||||
#define LMICbandplan_joinAcceptChannelClear() LMICbandplan_initDefaultChannels(/* normal, not join */ 0)
|
||||
|
||||
enum { BAND_MILLI = 0, BAND_CENTI = 1, BAND_DECI = 2, BAND_AUX = 3 };
|
||||
|
||||
// there's a CFList on joins for EU-like plans
|
||||
#define LMICbandplan_hasJoinCFlist() (1)
|
||||
|
||||
#define LMICbandplan_advanceBeaconChannel() \
|
||||
do { /* nothing */ } while (0)
|
||||
|
||||
#define LMICbandplan_resetDefaultChannels() \
|
||||
do { /* nothing */ } while (0)
|
||||
|
||||
#define LMICbandplan_setSessionInitDefaultChannels() \
|
||||
do { LMICbandplan_initDefaultChannels(/* normal, not join */ 0); } while (0)
|
||||
|
||||
u1_t LMICeulike_mapChannels(u1_t chpage, u2_t chmap);
|
||||
#define LMICbandplan_mapChannels(c, m) LMICeulike_mapChannels(c, m)
|
||||
|
||||
void LMICeulike_initJoinLoop(u1_t nDefaultChannels, s1_t adrTxPow);
|
||||
|
||||
#define LMICbandplan_setRx1Params() \
|
||||
do { /*LMIC.freq/rps remain unchanged*/ } while (0)
|
||||
|
||||
void LMICeulike_updateTx(ostime_t txbeg);
|
||||
#define LMICbandplan_updateTx(t) LMICeulike_updateTx(t)
|
||||
|
||||
ostime_t LMICeulike_nextJoinState(uint8_t nDefaultChannels);
|
||||
|
||||
static inline ostime_t LMICeulike_nextJoinTime(ostime_t now) {
|
||||
return now;
|
||||
}
|
||||
#define LMICbandplan_nextJoinTime(now) LMICeulike_nextJoinTime(now)
|
||||
|
||||
#define LMICbandplan_init() \
|
||||
do { /* nothing */ } while (0)
|
||||
|
||||
#endif // _lmic_eu_like_h_
|
205
src/lmic/lmic_in866.c
Executable file
205
src/lmic/lmic_in866.c
Executable file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LMIC_DR_LEGACY 0
|
||||
|
||||
#include "lmic_bandplan.h"
|
||||
|
||||
#if defined(CFG_in866)
|
||||
// ================================================================================
|
||||
//
|
||||
// BEG: IN866 related stuff
|
||||
//
|
||||
|
||||
CONST_TABLE(u1_t, _DR2RPS_CRC)[] = {
|
||||
ILLEGAL_RPS,
|
||||
(u1_t)MAKERPS(SF12, BW125, CR_4_5, 0, 0), // [0]
|
||||
(u1_t)MAKERPS(SF11, BW125, CR_4_5, 0, 0), // [1]
|
||||
(u1_t)MAKERPS(SF10, BW125, CR_4_5, 0, 0), // [2]
|
||||
(u1_t)MAKERPS(SF9, BW125, CR_4_5, 0, 0), // [3]
|
||||
(u1_t)MAKERPS(SF8, BW125, CR_4_5, 0, 0), // [4]
|
||||
(u1_t)MAKERPS(SF7, BW125, CR_4_5, 0, 0), // [5]
|
||||
ILLEGAL_RPS, // [6]
|
||||
(u1_t)MAKERPS(FSK, BW125, CR_4_5, 0, 0), // [7]
|
||||
ILLEGAL_RPS
|
||||
};
|
||||
|
||||
static CONST_TABLE(u1_t, maxFrameLens)[] = { 59+5,59+5,59+5,123+5, 230+5, 230+5 };
|
||||
|
||||
uint8_t LMICin866_maxFrameLen(uint8_t dr) {
|
||||
if (dr < LENOF_TABLE(maxFrameLens))
|
||||
return TABLE_GET_U1(maxFrameLens, dr);
|
||||
else
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
static CONST_TABLE(s1_t, TXPOWLEVELS)[] = {
|
||||
20, 14, 11, 8, 5, 2, 0,0, 0,0,0,0, 0,0,0,0
|
||||
};
|
||||
|
||||
int8_t LMICin866_pow2dBm(uint8_t mcmd_ladr_p1) {
|
||||
return TABLE_GET_S1(TXPOWLEVELS, (mcmd_ladr_p1&MCMD_LADR_POW_MASK)>>MCMD_LADR_POW_SHIFT);
|
||||
}
|
||||
|
||||
// only used in this module, but used by variant macro dr2hsym().
|
||||
static CONST_TABLE(ostime_t, DR2HSYM_osticks)[] = {
|
||||
us2osticksRound(128 << 7), // DR_SF12
|
||||
us2osticksRound(128 << 6), // DR_SF11
|
||||
us2osticksRound(128 << 5), // DR_SF10
|
||||
us2osticksRound(128 << 4), // DR_SF9
|
||||
us2osticksRound(128 << 3), // DR_SF8
|
||||
us2osticksRound(128 << 2), // DR_SF7
|
||||
us2osticksRound(128 << 1), // --
|
||||
us2osticksRound(80) // FSK -- not used (time for 1/2 byte)
|
||||
};
|
||||
|
||||
ostime_t LMICin866_dr2hsym(uint8_t dr) {
|
||||
return TABLE_GET_OSTIME(DR2HSYM_osticks, dr);
|
||||
}
|
||||
|
||||
|
||||
// All frequencies are marked as BAND_MILLI, and we don't do duty-cycle. But this lets
|
||||
// us reuse code.
|
||||
enum { NUM_DEFAULT_CHANNELS = 3 };
|
||||
static CONST_TABLE(u4_t, iniChannelFreq)[NUM_DEFAULT_CHANNELS] = {
|
||||
// Default operational frequencies
|
||||
IN866_F1 | BAND_MILLI,
|
||||
IN866_F2 | BAND_MILLI,
|
||||
IN866_F3 | BAND_MILLI,
|
||||
};
|
||||
|
||||
// india ignores join, becuase the channel setup is the same either way.
|
||||
void LMICin866_initDefaultChannels(bit_t join) {
|
||||
os_clearMem(&LMIC.channelFreq, sizeof(LMIC.channelFreq));
|
||||
os_clearMem(&LMIC.channelDrMap, sizeof(LMIC.channelDrMap));
|
||||
os_clearMem(&LMIC.bands, sizeof(LMIC.bands));
|
||||
|
||||
LMIC.channelMap = (1 << NUM_DEFAULT_CHANNELS) - 1;
|
||||
for (u1_t fu = 0; fu<NUM_DEFAULT_CHANNELS; fu++) {
|
||||
LMIC.channelFreq[fu] = TABLE_GET_U4(iniChannelFreq, fu);
|
||||
LMIC.channelDrMap[fu] = DR_RANGE_MAP(IN866_DR_SF12, IN866_DR_SF7);
|
||||
}
|
||||
|
||||
LMIC.bands[BAND_MILLI].txcap = 1; // no limit, in effect.
|
||||
LMIC.bands[BAND_MILLI].txpow = IN866_TX_EIRP_MAX_DBM;
|
||||
LMIC.bands[BAND_MILLI].lastchnl = os_getRndU1() % MAX_CHANNELS;
|
||||
LMIC.bands[BAND_MILLI].avail = os_getTime();
|
||||
}
|
||||
|
||||
bit_t LMIC_setupBand(u1_t bandidx, s1_t txpow, u2_t txcap) {
|
||||
if (bandidx > BAND_MILLI) return 0;
|
||||
//band_t* b = &LMIC.bands[bandidx];
|
||||
xref2band_t b = &LMIC.bands[bandidx];
|
||||
b->txpow = txpow;
|
||||
b->txcap = txcap;
|
||||
b->avail = os_getTime();
|
||||
b->lastchnl = os_getRndU1() % MAX_CHANNELS;
|
||||
return 1;
|
||||
}
|
||||
|
||||
bit_t LMIC_setupChannel(u1_t chidx, u4_t freq, u2_t drmap, s1_t band) {
|
||||
if (chidx >= MAX_CHANNELS)
|
||||
return 0;
|
||||
if (band == -1) {
|
||||
freq |= BAND_MILLI;
|
||||
} else {
|
||||
if (band > BAND_MILLI) return 0;
|
||||
freq = (freq&~3) | band;
|
||||
}
|
||||
LMIC.channelFreq[chidx] = freq;
|
||||
LMIC.channelDrMap[chidx] = drmap == 0 ? DR_RANGE_MAP(IN866_DR_SF12, IN866_DR_SF7) : drmap;
|
||||
LMIC.channelMap |= 1 << chidx; // enabled right away
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u4_t LMICin866_convFreq(xref2cu1_t ptr) {
|
||||
u4_t freq = (os_rlsbf4(ptr - 1) >> 8) * 100;
|
||||
if (freq < IN866_FREQ_MIN || freq > IN866_FREQ_MAX)
|
||||
freq = 0;
|
||||
return freq;
|
||||
}
|
||||
|
||||
// return the next time, but also do channel hopping here
|
||||
// since there's no duty cycle limitation, and no dwell limitation,
|
||||
// we simply loop through the channels sequentially.
|
||||
ostime_t LMICin866_nextTx(ostime_t now) {
|
||||
const u1_t band = BAND_MILLI;
|
||||
|
||||
for (u1_t ci = 0; ci < MAX_CHANNELS; ci++) {
|
||||
// Find next channel in given band
|
||||
u1_t chnl = LMIC.bands[band].lastchnl;
|
||||
for (u1_t ci = 0; ci<MAX_CHANNELS; ci++) {
|
||||
if ((chnl = (chnl + 1)) >= MAX_CHANNELS)
|
||||
chnl -= MAX_CHANNELS;
|
||||
if ((LMIC.channelMap & (1 << chnl)) != 0 && // channel enabled
|
||||
(LMIC.channelDrMap[chnl] & (1 << (LMIC.datarate & 0xF))) != 0 &&
|
||||
band == (LMIC.channelFreq[chnl] & 0x3)) { // in selected band
|
||||
LMIC.txChnl = LMIC.bands[band].lastchnl = chnl;
|
||||
return now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no enabled channel found! just use the last channel.
|
||||
return now;
|
||||
}
|
||||
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
void LMICin866_setBcnRxParams(void) {
|
||||
LMIC.dataLen = 0;
|
||||
LMIC.freq = LMIC.channelFreq[LMIC.bcnChnl] & ~(u4_t)3;
|
||||
LMIC.rps = setIh(setNocrc(dndr2rps((dr_t)DR_BCN), 1), LEN_BCN);
|
||||
}
|
||||
#endif // !DISABLE_BEACONS
|
||||
|
||||
#if !defined(DISABLE_JOIN)
|
||||
ostime_t LMICin866_nextJoinState(void) {
|
||||
return LMICeulike_nextJoinState(NUM_DEFAULT_CHANNELS);
|
||||
}
|
||||
#endif // !DISABLE_JOIN
|
||||
|
||||
// txDone handling for FSK.
|
||||
void
|
||||
LMICin866_txDoneFSK(ostime_t delay, osjobcb_t func) {
|
||||
LMIC.rxtime = LMIC.txend + delay - PRERX_FSK*us2osticksRound(160);
|
||||
LMIC.rxsyms = RXLEN_FSK;
|
||||
os_setTimedCallback(&LMIC.osjob, LMIC.rxtime - RX_RAMPUP, func);
|
||||
}
|
||||
|
||||
void
|
||||
LMICin866_initJoinLoop(void) {
|
||||
LMICeulike_initJoinLoop(NUM_DEFAULT_CHANNELS, /* adr dBm */ IN866_TX_EIRP_MAX_DBM);
|
||||
}
|
||||
|
||||
//
|
||||
// END: IN866 related stuff
|
||||
//
|
||||
// ================================================================================
|
||||
#endif
|
209
src/lmic/lmic_us915.c
Executable file
209
src/lmic/lmic_us915.c
Executable file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LMIC_DR_LEGACY 0
|
||||
|
||||
#include "lmic_bandplan.h"
|
||||
|
||||
#if defined(CFG_us915)
|
||||
// ================================================================================
|
||||
//
|
||||
// BEG: US915 related stuff
|
||||
//
|
||||
|
||||
CONST_TABLE(u1_t, _DR2RPS_CRC)[] = {
|
||||
ILLEGAL_RPS, // [-1]
|
||||
MAKERPS(SF10, BW125, CR_4_5, 0, 0), // [0]
|
||||
MAKERPS(SF9 , BW125, CR_4_5, 0, 0), // [1]
|
||||
MAKERPS(SF8 , BW125, CR_4_5, 0, 0), // [2]
|
||||
MAKERPS(SF7 , BW125, CR_4_5, 0, 0), // [3]
|
||||
MAKERPS(SF8 , BW500, CR_4_5, 0, 0), // [4]
|
||||
ILLEGAL_RPS , // [5]
|
||||
ILLEGAL_RPS , // [6]
|
||||
ILLEGAL_RPS , // [7]
|
||||
MAKERPS(SF12, BW500, CR_4_5, 0, 0), // [8]
|
||||
MAKERPS(SF11, BW500, CR_4_5, 0, 0), // [9]
|
||||
MAKERPS(SF10, BW500, CR_4_5, 0, 0), // [10]
|
||||
MAKERPS(SF9 , BW500, CR_4_5, 0, 0), // [11]
|
||||
MAKERPS(SF8 , BW500, CR_4_5, 0, 0), // [12]
|
||||
MAKERPS(SF7 , BW500, CR_4_5, 0, 0), // [13]
|
||||
ILLEGAL_RPS // [14]
|
||||
};
|
||||
|
||||
static CONST_TABLE(u1_t, maxFrameLens)[] = { 24,66,142,255,255,255,255,255, 66,142 };
|
||||
|
||||
uint8_t LMICus915_maxFrameLen(uint8_t dr) {
|
||||
if (dr < LENOF_TABLE(maxFrameLens))
|
||||
return TABLE_GET_U1(maxFrameLens, dr);
|
||||
else
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
static CONST_TABLE(ostime_t, DR2HSYM_osticks)[] = {
|
||||
us2osticksRound(128 << 5), // DR_SF10 DR_SF12CR
|
||||
us2osticksRound(128 << 4), // DR_SF9 DR_SF11CR
|
||||
us2osticksRound(128 << 3), // DR_SF8 DR_SF10CR
|
||||
us2osticksRound(128 << 2), // DR_SF7 DR_SF9CR
|
||||
us2osticksRound(128 << 1), // DR_SF8C DR_SF8CR
|
||||
us2osticksRound(128 << 0) // ------ DR_SF7CR
|
||||
};
|
||||
|
||||
ostime_t LMICus915_dr2hsym(uint8_t dr) {
|
||||
return TABLE_GET_OSTIME(DR2HSYM_osticks, (dr) & 7); // map DR_SFnCR -> 0-6
|
||||
}
|
||||
|
||||
|
||||
|
||||
u4_t LMICus915_convFreq(xref2cu1_t ptr) {
|
||||
u4_t freq = (os_rlsbf4(ptr - 1) >> 8) * 100;
|
||||
if (freq < US915_FREQ_MIN || freq > US915_FREQ_MAX)
|
||||
freq = 0;
|
||||
return freq;
|
||||
}
|
||||
|
||||
bit_t LMIC_setupChannel(u1_t chidx, u4_t freq, u2_t drmap, s1_t band) {
|
||||
if (chidx < 72 || chidx >= 72 + MAX_XCHANNELS)
|
||||
return 0; // channels 0..71 are hardwired
|
||||
LMIC.xchFreq[chidx - 72] = freq;
|
||||
// TODO(tmm@mcci.com): don't use US SF directly, use something from the LMIC context or a static const
|
||||
LMIC.xchDrMap[chidx - 72] = drmap == 0 ? DR_RANGE_MAP(US915_DR_SF10, US915_DR_SF8C) : drmap;
|
||||
LMIC.channelMap[chidx >> 4] |= (1 << (chidx & 0xF));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LMIC_disableChannel(u1_t channel) {
|
||||
if (channel < 72 + MAX_XCHANNELS) {
|
||||
if (ENABLED_CHANNEL(channel)) {
|
||||
if (IS_CHANNEL_125khz(channel))
|
||||
LMIC.activeChannels125khz--;
|
||||
else if (IS_CHANNEL_500khz(channel))
|
||||
LMIC.activeChannels500khz--;
|
||||
}
|
||||
LMIC.channelMap[channel >> 4] &= ~(1 << (channel & 0xF));
|
||||
}
|
||||
}
|
||||
|
||||
void LMIC_enableChannel(u1_t channel) {
|
||||
if (channel < 72 + MAX_XCHANNELS) {
|
||||
if (!ENABLED_CHANNEL(channel)) {
|
||||
if (IS_CHANNEL_125khz(channel))
|
||||
LMIC.activeChannels125khz++;
|
||||
else if (IS_CHANNEL_500khz(channel))
|
||||
LMIC.activeChannels500khz++;
|
||||
}
|
||||
LMIC.channelMap[channel >> 4] |= (1 << (channel & 0xF));
|
||||
}
|
||||
}
|
||||
|
||||
void LMIC_enableSubBand(u1_t band) {
|
||||
ASSERT(band < 8);
|
||||
u1_t start = band * 8;
|
||||
u1_t end = start + 8;
|
||||
|
||||
// enable all eight 125 kHz channels in this subband
|
||||
for (int channel = start; channel < end; ++channel)
|
||||
LMIC_enableChannel(channel);
|
||||
|
||||
// there's a single 500 kHz channel associated with
|
||||
// each group of 8 125 kHz channels. Enable it, too.
|
||||
LMIC_enableChannel(64 + band);
|
||||
}
|
||||
void LMIC_disableSubBand(u1_t band) {
|
||||
ASSERT(band < 8);
|
||||
u1_t start = band * 8;
|
||||
u1_t end = start + 8;
|
||||
|
||||
// disable all eight 125 kHz channels in this subband
|
||||
for (int channel = start; channel < end; ++channel)
|
||||
LMIC_disableChannel(channel);
|
||||
|
||||
// there's a single 500 kHz channel associated with
|
||||
// each group of 8 125 kHz channels. Disable it, too.
|
||||
LMIC_disableChannel(64 + band);
|
||||
}
|
||||
void LMIC_selectSubBand(u1_t band) {
|
||||
ASSERT(band < 8);
|
||||
for (int b = 0; b<8; ++b) {
|
||||
if (band == b)
|
||||
LMIC_enableSubBand(b);
|
||||
else
|
||||
LMIC_disableSubBand(b);
|
||||
}
|
||||
}
|
||||
|
||||
void LMICus915_updateTx(ostime_t txbeg) {
|
||||
u1_t chnl = LMIC.txChnl;
|
||||
if (chnl < 64) {
|
||||
LMIC.freq = US915_125kHz_UPFBASE + chnl*US915_125kHz_UPFSTEP;
|
||||
if (LMIC.activeChannels125khz >= 50)
|
||||
LMIC.txpow = 30;
|
||||
else
|
||||
LMIC.txpow = 21;
|
||||
} else {
|
||||
// at 500kHz bandwidth, we're allowed more power.
|
||||
LMIC.txpow = 26;
|
||||
if (chnl < 64 + 8) {
|
||||
LMIC.freq = US915_500kHz_UPFBASE + (chnl - 64)*US915_500kHz_UPFSTEP;
|
||||
}
|
||||
else {
|
||||
ASSERT(chnl < 64 + 8 + MAX_XCHANNELS);
|
||||
LMIC.freq = LMIC.xchFreq[chnl - 72];
|
||||
}
|
||||
}
|
||||
|
||||
// Update global duty cycle stats
|
||||
if (LMIC.globalDutyRate != 0) {
|
||||
ostime_t airtime = calcAirTime(LMIC.rps, LMIC.dataLen);
|
||||
LMIC.globalDutyAvail = txbeg + (airtime << LMIC.globalDutyRate);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(DISABLE_BEACONS)
|
||||
void LMICus915_setBcnRxParams(void) {
|
||||
LMIC.dataLen = 0;
|
||||
LMIC.freq = US915_500kHz_DNFBASE + LMIC.bcnChnl * US915_500kHz_DNFSTEP;
|
||||
LMIC.rps = setIh(setNocrc(dndr2rps((dr_t)DR_BCN), 1), LEN_BCN);
|
||||
}
|
||||
#endif // !DISABLE_BEACONS
|
||||
|
||||
// TODO(tmm@mcci.com): parmeterize for US-like
|
||||
void LMICus915_setRx1Params(void) {
|
||||
LMIC.freq = US915_500kHz_DNFBASE + (LMIC.txChnl & 0x7) * US915_500kHz_DNFSTEP;
|
||||
if( /* TX datarate */LMIC.dndr < US915_DR_SF8C )
|
||||
LMIC.dndr += US915_DR_SF10CR - US915_DR_SF10;
|
||||
else if( LMIC.dndr == US915_DR_SF8C )
|
||||
LMIC.dndr = US915_DR_SF7CR;
|
||||
LMIC.rps = dndr2rps(LMIC.dndr);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// END: US915 related stuff
|
||||
//
|
||||
// ================================================================================
|
||||
#endif
|
257
src/lmic/lmic_us_like.c
Executable file
257
src/lmic/lmic_us_like.c
Executable file
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LMIC_DR_LEGACY 0
|
||||
|
||||
#include "lmic_bandplan.h"
|
||||
|
||||
#if CFG_LMIC_US_like
|
||||
|
||||
#ifndef LMICuslike_getFirst500kHzDR
|
||||
# error "LMICuslike_getFirst500kHzDR() not defined by bandplan"
|
||||
#endif
|
||||
|
||||
static void setNextChannel(uint start, uint end, uint count) {
|
||||
ASSERT(count>0);
|
||||
ASSERT(start<end);
|
||||
ASSERT(count <= (end - start));
|
||||
// We used to pick a random channel once and then just increment. That is not per spec.
|
||||
// Now we use a new random number each time, because they are not very expensive.
|
||||
// Regarding the algo below, we cannot pick a number and scan until we hit an enabled channel.
|
||||
// That would result in the first enabled channel following a set of disabled ones
|
||||
// being used more frequently than the other enabled channels.
|
||||
|
||||
// Last used channel is in range. It is not a candidate, per spec.
|
||||
uint lastTxChan = LMIC.txChnl;
|
||||
if (start <= lastTxChan && lastTxChan<end &&
|
||||
// Adjust count only if still enabled. Otherwise, no chance of selection.
|
||||
ENABLED_CHANNEL(lastTxChan)) {
|
||||
--count;
|
||||
if (count == 0) {
|
||||
return; // Only one active channel, so keep using it.
|
||||
}
|
||||
}
|
||||
|
||||
uint nth = os_getRndU1() % count;
|
||||
for (u1_t chnl = start; chnl<end; chnl++) {
|
||||
// Scan for nth enabled channel that is not the last channel used
|
||||
if (chnl != lastTxChan && ENABLED_CHANNEL(chnl) && (nth--) == 0) {
|
||||
LMIC.txChnl = chnl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// No feasible channel found! Keep old one.
|
||||
}
|
||||
|
||||
|
||||
|
||||
bit_t LMIC_setupBand(u1_t bandidx, s1_t txpow, u2_t txcap) {
|
||||
// nothing; just succeed.
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void LMICuslike_initDefaultChannels(bit_t fJoin) {
|
||||
// things work the same for join as normal.
|
||||
for (u1_t i = 0; i<4; i++)
|
||||
LMIC.channelMap[i] = 0xFFFF;
|
||||
LMIC.channelMap[4] = 0x00FF;
|
||||
LMIC.activeChannels125khz = 64;
|
||||
LMIC.activeChannels500khz = 8;
|
||||
}
|
||||
|
||||
u1_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap) {
|
||||
/*
|
||||
|| MCMD_LADR_CHP_125ON and MCMD_LADR_CHP_125OFF are special. The
|
||||
|| channel map appllies to 500kHz (ch 64..71) and in addition
|
||||
|| all channels 0..63 are turned off or on. MCMC_LADR_CHP_BANK
|
||||
|| is also special, in that it enables subbands.
|
||||
*/
|
||||
u1_t base, top;
|
||||
|
||||
if (chpage < MCMD_LADR_CHP_USLIKE_SPECIAL) {
|
||||
// operate on channels 0..15, 16..31, 32..47, 48..63
|
||||
base = chpage << 4;
|
||||
top = base + 16;
|
||||
if (base == 64) {
|
||||
if (chmap & 0xFF00) {
|
||||
// those are reserved bits, fail.
|
||||
return 0;
|
||||
}
|
||||
top = 72;
|
||||
}
|
||||
} else if (chpage == MCMD_LADR_CHP_BANK) {
|
||||
if (chmap & 0xFF00) {
|
||||
// those are resreved bits, fail.
|
||||
return 0;
|
||||
}
|
||||
// each bit enables a bank of channels
|
||||
for (u1_t subband = 0; subband < 8; ++subband, chmap >>= 1) {
|
||||
if (chmap & 1) {
|
||||
LMIC_enableSubBand(subband);
|
||||
} else {
|
||||
LMIC_disableSubBand(subband);
|
||||
}
|
||||
|
||||
// don't change any channels below
|
||||
base = top = 0;
|
||||
}
|
||||
} else if (chpage == MCMD_LADR_CHP_125ON || chpage == MCMD_LADR_CHP_125OFF) {
|
||||
u1_t const en125 = chpage == MCMD_LADR_CHP_125ON;
|
||||
|
||||
// enable or disable all 125kHz channels
|
||||
for (u1_t chnl = 0; chnl < 64; ++chnl) {
|
||||
if (en125)
|
||||
LMIC_enableChannel(chnl);
|
||||
else
|
||||
LMIC_disableChannel(chnl);
|
||||
}
|
||||
|
||||
// then apply mask to top 8 channels.
|
||||
base = 64;
|
||||
top = 72;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// apply chmap to channels in [base..top-1].
|
||||
// Use enable/disable channel to keep activeChannel counts in sync.
|
||||
for (u1_t chnl = base; chnl < top; ++chnl, chmap >>= 1) {
|
||||
if (chmap & 0x0001)
|
||||
LMIC_enableChannel(chnl);
|
||||
else
|
||||
LMIC_disableChannel(chnl);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// US does not have duty cycling - return now as earliest TX time
|
||||
// but also do the channel hopping dance.
|
||||
ostime_t LMICuslike_nextTx(ostime_t now) {
|
||||
// TODO(tmm@mcci.com): use a static const for US-like
|
||||
if (LMIC.datarate >= LMICuslike_getFirst500kHzDR()) { // 500kHz
|
||||
ASSERT(LMIC.activeChannels500khz>0);
|
||||
setNextChannel(64, 64 + 8, LMIC.activeChannels500khz);
|
||||
}
|
||||
else { // 125kHz
|
||||
ASSERT(LMIC.activeChannels125khz>0);
|
||||
setNextChannel(0, 64, LMIC.activeChannels125khz);
|
||||
}
|
||||
return now;
|
||||
}
|
||||
|
||||
#if !defined(DISABLE_JOIN)
|
||||
void LMICuslike_initJoinLoop(void) {
|
||||
// set an initial condition so that setNextChannel()'s preconds are met
|
||||
LMIC.txChnl = 0;
|
||||
|
||||
// then chose a new channel. This gives us a random first channel for
|
||||
// the join. Minor nit: if channel 0 is enabled, it will never be used
|
||||
// as the first join channel. The join logic uses the current txChnl,
|
||||
// then changes after the rx window expires; so we need to set a valid
|
||||
// starting point.
|
||||
setNextChannel(0, 64, LMIC.activeChannels125khz);
|
||||
|
||||
// initialize the adrTxPower.
|
||||
// TODO(tmm@mcci.com): is this right for all US-like regions
|
||||
LMIC.adrTxPow = 20; // dBm
|
||||
ASSERT((LMIC.opmode & OP_NEXTCHNL) == 0);
|
||||
|
||||
// make sure LMIC.txend is valid.
|
||||
LMIC.txend = os_getTime();
|
||||
|
||||
// make sure the datarate is set to DR0 per LoRaWAN regional reqts V1.0.2,
|
||||
// section 2.2.2
|
||||
// TODO(tmm@mcci.com): parameterize this for US-like
|
||||
LMICcore_setDrJoin(DRCHG_SET, LORAWAN_DR0);
|
||||
|
||||
// TODO(tmm@mcci.com) need to implement the transmit randomization and
|
||||
// duty cycle restrictions from LoRaWAN V1.0.2 section 7.
|
||||
}
|
||||
#endif // !DISABLE_JOIN
|
||||
|
||||
#if !defined(DISABLE_JOIN)
|
||||
//
|
||||
// TODO(tmm@mcci.com):
|
||||
//
|
||||
// The definition of this is a little strange. this seems to return a time, but
|
||||
// in reality it returns 0 if the caller should continue scanning through
|
||||
// channels, and 1 if the caller has scanned all channels on this session,
|
||||
// and therefore should reset to the beginning. The IBM 1.6 code is the
|
||||
// same way, so apparently I just carried this across. We should declare
|
||||
// as bool_t and change callers to use the result clearly as a flag.
|
||||
//
|
||||
ostime_t LMICuslike_nextJoinState(void) {
|
||||
// Try the following:
|
||||
// DR0 (SF10) on a random channel 0..63
|
||||
// (honoring enable mask)
|
||||
// DR4 (SF8C) on a random 500 kHz channel 64..71
|
||||
// (always determined by
|
||||
// previously selected
|
||||
// 125 kHz channel)
|
||||
//
|
||||
u1_t failed = 0;
|
||||
// TODO(tmm@mcci.com) parameterize for US-like
|
||||
if (LMIC.datarate != LMICuslike_getFirst500kHzDR()) {
|
||||
// assume that 500 kHz equiv of last 125 kHz channel
|
||||
// is also enabled, and use it next.
|
||||
LMIC.txChnl = 64 + (LMIC.txChnl >> 3);
|
||||
LMICcore_setDrJoin(DRCHG_SET, LMICuslike_getFirst500kHzDR());
|
||||
}
|
||||
else {
|
||||
setNextChannel(0, 64, LMIC.activeChannels125khz);
|
||||
|
||||
// TODO(tmm@mcci.com) parameterize
|
||||
s1_t dr = LORAWAN_DR0;
|
||||
if ((++LMIC.txCnt & 0x7) == 0) {
|
||||
failed = 1; // All DR exhausted - signal failed
|
||||
}
|
||||
LMICcore_setDrJoin(DRCHG_SET, dr);
|
||||
}
|
||||
LMIC.opmode &= ~OP_NEXTCHNL;
|
||||
|
||||
// TODO(tmm@mcci.com): change delay to (0:1) secs + a known t0, but randomized;
|
||||
// starting adding a bias after 1 hour, 25 hours, etc.; and limit the duty
|
||||
// cycle on power up. For testability, add a way to set the join start time
|
||||
// externally (a test API) so we can check this feature.
|
||||
// See https://github.com/mcci-catena/arduino-lmic/issues/2
|
||||
// Current code doesn't match LoRaWAN 1.0.2 requirements.
|
||||
|
||||
LMIC.txend = os_getTime() +
|
||||
(isTESTMODE()
|
||||
// Avoid collision with JOIN ACCEPT being sent by GW (but we missed it - GW is still busy)
|
||||
? DNW2_SAFETY_ZONE
|
||||
// Otherwise: randomize join (street lamp case):
|
||||
// SF10:16, SF9=8,..SF8C:1secs
|
||||
: LMICcore_rndDelay(16 >> LMIC.datarate));
|
||||
// 1 - triggers EV_JOIN_FAILED event
|
||||
return failed;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // CFG_LMIC_US_like
|
100
src/lmic/lmic_us_like.h
Executable file
100
src/lmic/lmic_us_like.h
Executable file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lmic_us_like_h_
|
||||
# define _lmic_us_like_h_
|
||||
|
||||
// make sure we want US-like code
|
||||
#if !CFG_LMIC_US_like
|
||||
# error "lmic not configured for us-like bandplan"
|
||||
#endif
|
||||
|
||||
// TODO(tmm@mcci.com): this should come from the lmic.h or lorabase.h file; and
|
||||
// it's probably affected by the fix to this issue:
|
||||
// https://github.com/mcci-catena/arduino-lmic/issues/2
|
||||
#define DNW2_SAFETY_ZONE ms2osticks(750)
|
||||
|
||||
#define IS_CHANNEL_125khz(c) (c<64)
|
||||
#define IS_CHANNEL_500khz(c) (c>=64 && c<72)
|
||||
#define ENABLED_CHANNEL(chnl) ((LMIC.channelMap[(chnl >> 4)] & (1<<(chnl & 0x0F))) != 0)
|
||||
|
||||
// provide the isValidBeacon1 function -- int for bool.
|
||||
static inline int
|
||||
LMICuslike_isValidBeacon1(const uint8_t *d) {
|
||||
return os_rlsbf2(&d[OFF_BCN_CRC1]) != os_crc16(d, OFF_BCN_CRC1);
|
||||
}
|
||||
|
||||
#define LMICbandplan_isValidBeacon1(pFrame) LMICuslike_isValidBeacon1(pFrame)
|
||||
|
||||
// provide a default for LMICbandplan_isFSK()
|
||||
#define LMICbandplan_isFSK() (0)
|
||||
|
||||
// provide a default LMICbandplan_txDoneFSK()
|
||||
#define LMICbandplan_txDoneFSK(delay, func) do { } while (0)
|
||||
|
||||
// provide a default LMICbandplan_joinAcceptChannelClear()
|
||||
#define LMICbandplan_joinAcceptChannelClear() do { } while (0)
|
||||
|
||||
// no CFList on joins for US-like plans
|
||||
#define LMICbandplan_hasJoinCFlist() (0)
|
||||
|
||||
#define LMICbandplan_advanceBeaconChannel() \
|
||||
do { LMIC.bcnChnl = (LMIC.bcnChnl+1) & 7; } while (0)
|
||||
|
||||
// TODO(tmm@mcci.com): decide whether we want to do this on every
|
||||
// reset or just restore the last sub-band selected by the user.
|
||||
#define LMICbandplan_resetDefaultChannels() \
|
||||
LMICbandplan_initDefaultChannels(/* normal */ 0)
|
||||
|
||||
void LMICuslike_initDefaultChannels(bit_t fJoin);
|
||||
#define LMICbandplan_initDefaultChannels(fJoin) LMICuslike_initDefaultChannels(fJoin)
|
||||
|
||||
#define LMICbandplan_setSessionInitDefaultChannels() \
|
||||
do { /* nothing */} while (0)
|
||||
|
||||
u1_t LMICuslike_mapChannels(u1_t chpage, u2_t chmap);
|
||||
#define LMICbandplan_mapChannels(chpage, chmap) LMICuslike_mapChannels(chpage, chmap)
|
||||
|
||||
ostime_t LMICuslike_nextTx(ostime_t now);
|
||||
#define LMICbandplan_nextTx(now) LMICuslike_nextTx(now)
|
||||
|
||||
void LMICuslike_initJoinLoop(void);
|
||||
#define LMICbandplan_initJoinLoop() LMICuslike_initJoinLoop()
|
||||
|
||||
ostime_t LMICuslike_nextJoinState(void);
|
||||
#define LMICbandplan_nextJoinState() LMICuslike_nextJoinState();
|
||||
|
||||
static inline ostime_t LMICeulike_nextJoinTime(ostime_t now) {
|
||||
return now;
|
||||
}
|
||||
#define LMICbandplan_nextJoinTime(now) LMICeulike_nextJoinTime(now)
|
||||
|
||||
#define LMICbandplan_init() \
|
||||
do { /* nothing */ } while (0)
|
||||
|
||||
#endif // _lmic_us_like_h_
|
335
src/lmic/lmic_util.c
Executable file
335
src/lmic/lmic_util.c
Executable file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
|
||||
Module: lmic_util.c
|
||||
|
||||
Function:
|
||||
Encoding and decoding utilities for LMIC clients.
|
||||
|
||||
Copyright & License:
|
||||
See accompanying LICENSE file.
|
||||
|
||||
Author:
|
||||
Terry Moore, MCCI September 2019
|
||||
|
||||
*/
|
||||
|
||||
#include "lmic_util.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
|
||||
Name: LMIC_f2sflt16()
|
||||
|
||||
Function:
|
||||
Encode a floating point number into a uint16_t.
|
||||
|
||||
Definition:
|
||||
uint16_t LMIC_f2sflt16(
|
||||
float f
|
||||
);
|
||||
|
||||
Description:
|
||||
The float to be transmitted must be a number in the range (-1.0, 1.0).
|
||||
It is converted to 16-bit integer formatted as follows:
|
||||
|
||||
bits 15: sign
|
||||
bits 14..11: biased exponent
|
||||
bits 10..0: mantissa
|
||||
|
||||
The float is properly rounded, and saturates.
|
||||
|
||||
Note that the encoded value is sign/magnitude format, rather than
|
||||
two's complement for negative values.
|
||||
|
||||
Returns:
|
||||
0xFFFF for negative values <= 1.0;
|
||||
0x7FFF for positive values >= 1.0;
|
||||
Otherwise an appropriate float.
|
||||
|
||||
*/
|
||||
|
||||
uint16_t
|
||||
LMIC_f2sflt16(
|
||||
float f
|
||||
)
|
||||
{
|
||||
if (f <= -1.0)
|
||||
return 0xFFFF;
|
||||
else if (f >= 1.0)
|
||||
return 0x7FFF;
|
||||
else
|
||||
{
|
||||
int iExp;
|
||||
float normalValue;
|
||||
uint16_t sign;
|
||||
|
||||
normalValue = frexpf(f, &iExp);
|
||||
|
||||
sign = 0;
|
||||
if (normalValue < 0)
|
||||
{
|
||||
// set the "sign bit" of the result
|
||||
// and work with the absolute value of normalValue.
|
||||
sign = 0x8000;
|
||||
normalValue = -normalValue;
|
||||
}
|
||||
|
||||
// abs(f) is supposed to be in [0..1), so useful exp
|
||||
// is [0..-15]
|
||||
iExp += 15;
|
||||
if (iExp < 0)
|
||||
iExp = 0;
|
||||
|
||||
// bit 15 is the sign
|
||||
// bits 14..11 are the exponent
|
||||
// bits 10..0 are the fraction
|
||||
// we conmpute the fraction and then decide if we need to round.
|
||||
uint16_t outputFraction = ldexpf(normalValue, 11) + 0.5;
|
||||
if (outputFraction >= (1 << 11u))
|
||||
{
|
||||
// reduce output fraction
|
||||
outputFraction = 1 << 10;
|
||||
// increase exponent
|
||||
++iExp;
|
||||
}
|
||||
|
||||
// check for overflow and return max instead.
|
||||
if (iExp > 15)
|
||||
return 0x7FFF | sign;
|
||||
|
||||
return (uint16_t)(sign | (iExp << 11u) | outputFraction);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Name: LMIC_f2sflt12()
|
||||
|
||||
Function:
|
||||
Encode a floating point number into a uint16_t using only 12 bits.
|
||||
|
||||
Definition:
|
||||
uint16_t LMIC_f2sflt16(
|
||||
float f
|
||||
);
|
||||
|
||||
Description:
|
||||
The float to be transmitted must be a number in the range (-1.0, 1.0).
|
||||
It is converted to 16-bit integer formatted as follows:
|
||||
|
||||
bits 15-12: zero
|
||||
bit 11: sign
|
||||
bits 10..7: biased exponent
|
||||
bits 6..0: mantissa
|
||||
|
||||
The float is properly rounded, and saturates.
|
||||
|
||||
Note that the encoded value is sign/magnitude format, rather than
|
||||
two's complement for negative values.
|
||||
|
||||
Returns:
|
||||
0xFFF for negative values <= 1.0;
|
||||
0x7FF for positive values >= 1.0;
|
||||
Otherwise an appropriate float.
|
||||
|
||||
*/
|
||||
|
||||
uint16_t
|
||||
LMIC_f2sflt12(
|
||||
float f
|
||||
)
|
||||
{
|
||||
if (f <= -1.0)
|
||||
return 0xFFF;
|
||||
else if (f >= 1.0)
|
||||
return 0x7FF;
|
||||
else
|
||||
{
|
||||
int iExp;
|
||||
float normalValue;
|
||||
uint16_t sign;
|
||||
|
||||
normalValue = frexpf(f, &iExp);
|
||||
|
||||
sign = 0;
|
||||
if (normalValue < 0)
|
||||
{
|
||||
// set the "sign bit" of the result
|
||||
// and work with the absolute value of normalValue.
|
||||
sign = 0x800;
|
||||
normalValue = -normalValue;
|
||||
}
|
||||
|
||||
// abs(f) is supposed to be in [0..1), so useful exp
|
||||
// is [0..-15]
|
||||
iExp += 15;
|
||||
if (iExp < 0)
|
||||
iExp = 0;
|
||||
|
||||
// bit 15 is the sign
|
||||
// bits 14..11 are the exponent
|
||||
// bits 10..0 are the fraction
|
||||
// we conmpute the fraction and then decide if we need to round.
|
||||
uint16_t outputFraction = ldexpf(normalValue, 7) + 0.5;
|
||||
if (outputFraction >= (1 << 7u))
|
||||
{
|
||||
// reduce output fraction
|
||||
outputFraction = 1 << 6;
|
||||
// increase exponent
|
||||
++iExp;
|
||||
}
|
||||
|
||||
// check for overflow and return max instead.
|
||||
if (iExp > 15)
|
||||
return 0x7FF | sign;
|
||||
|
||||
return (uint16_t)(sign | (iExp << 7u) | outputFraction);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Name: LMIC_f2uflt16()
|
||||
|
||||
Function:
|
||||
Encode a floating point number into a uint16_t.
|
||||
|
||||
Definition:
|
||||
uint16_t LMIC_f2uflt16(
|
||||
float f
|
||||
);
|
||||
|
||||
Description:
|
||||
The float to be transmitted must be a number in the range [0, 1.0).
|
||||
It is converted to 16-bit integer formatted as follows:
|
||||
|
||||
bits 15..12: biased exponent
|
||||
bits 11..0: mantissa
|
||||
|
||||
The float is properly rounded, and saturates.
|
||||
|
||||
Note that the encoded value is sign/magnitude format, rather than
|
||||
two's complement for negative values.
|
||||
|
||||
Returns:
|
||||
0x0000 for values < 0.0;
|
||||
0xFFFF for positive values >= 1.0;
|
||||
Otherwise an appropriate encoding of the input float.
|
||||
|
||||
*/
|
||||
|
||||
uint16_t
|
||||
LMIC_f2uflt16(
|
||||
float f
|
||||
)
|
||||
{
|
||||
if (f < 0.0)
|
||||
return 0;
|
||||
else if (f >= 1.0)
|
||||
return 0xFFFF;
|
||||
else
|
||||
{
|
||||
int iExp;
|
||||
float normalValue;
|
||||
|
||||
normalValue = frexpf(f, &iExp);
|
||||
|
||||
// f is supposed to be in [0..1), so useful exp
|
||||
// is [0..-15]
|
||||
iExp += 15;
|
||||
if (iExp < 0)
|
||||
// underflow.
|
||||
iExp = 0;
|
||||
|
||||
// bits 15..12 are the exponent
|
||||
// bits 11..0 are the fraction
|
||||
// we conmpute the fraction and then decide if we need to round.
|
||||
uint16_t outputFraction = ldexpf(normalValue, 12) + 0.5;
|
||||
if (outputFraction >= (1 << 12u))
|
||||
{
|
||||
// reduce output fraction
|
||||
outputFraction = 1 << 11;
|
||||
// increase exponent
|
||||
++iExp;
|
||||
}
|
||||
|
||||
// check for overflow and return max instead.
|
||||
if (iExp > 15)
|
||||
return 0xFFFF;
|
||||
|
||||
return (uint16_t)((iExp << 12u) | outputFraction);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Name: LMIC_f2uflt12()
|
||||
|
||||
Function:
|
||||
Encode positive floating point number into a uint16_t using only 12 bits.
|
||||
|
||||
Definition:
|
||||
uint16_t LMIC_f2sflt16(
|
||||
float f
|
||||
);
|
||||
|
||||
Description:
|
||||
The float to be transmitted must be a number in the range [0, 1.0).
|
||||
It is converted to 16-bit integer formatted as follows:
|
||||
|
||||
bits 15-12: zero
|
||||
bits 11..8: biased exponent
|
||||
bits 7..0: mantissa
|
||||
|
||||
The float is properly rounded, and saturates.
|
||||
|
||||
Returns:
|
||||
0x000 for negative values < 0.0;
|
||||
0xFFF for positive values >= 1.0;
|
||||
Otherwise an appropriate float.
|
||||
|
||||
*/
|
||||
|
||||
uint16_t
|
||||
LMIC_f2uflt12(
|
||||
float f
|
||||
)
|
||||
{
|
||||
if (f < 0.0)
|
||||
return 0x000;
|
||||
else if (f >= 1.0)
|
||||
return 0xFFF;
|
||||
else
|
||||
{
|
||||
int iExp;
|
||||
float normalValue;
|
||||
|
||||
normalValue = frexpf(f, &iExp);
|
||||
|
||||
// f is supposed to be in [0..1), so useful exp
|
||||
// is [0..-15]
|
||||
iExp += 15;
|
||||
if (iExp < 0)
|
||||
// graceful underflow
|
||||
iExp = 0;
|
||||
|
||||
// bits 11..8 are the exponent
|
||||
// bits 7..0 are the fraction
|
||||
// we conmpute the fraction and then decide if we need to round.
|
||||
uint16_t outputFraction = ldexpf(normalValue, 8) + 0.5;
|
||||
if (outputFraction >= (1 << 8u))
|
||||
{
|
||||
// reduce output fraction
|
||||
outputFraction = 1 << 7;
|
||||
// increase exponent
|
||||
++iExp;
|
||||
}
|
||||
|
||||
// check for overflow and return max instead.
|
||||
if (iExp > 15)
|
||||
return 0xFFF;
|
||||
|
||||
return (uint16_t)((iExp << 8u) | outputFraction);
|
||||
}
|
||||
}
|
34
src/lmic/lmic_util.h
Executable file
34
src/lmic/lmic_util.h
Executable file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
|
||||
Module: lmic_util.h
|
||||
|
||||
Function:
|
||||
Declare encoding and decoding utilities for LMIC clients.
|
||||
|
||||
Copyright & License:
|
||||
See accompanying LICENSE file.
|
||||
|
||||
Author:
|
||||
Terry Moore, MCCI September 2019
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _LMIC_UTIL_H_
|
||||
# define _LMIC_UTIL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint16_t LMIC_f2sflt16(float);
|
||||
uint16_t LMIC_f2sflt12(float);
|
||||
uint16_t LMIC_f2uflt16(float);
|
||||
uint16_t LMIC_f2uflt12(float);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LMIC_UTIL_H_ */
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyritght (c) 2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -29,7 +30,7 @@
|
||||
#define _lorabase_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
// ================================================================================
|
||||
@ -48,8 +49,6 @@ typedef u2_t rps_t;
|
||||
TYPEDEF_xref2rps_t;
|
||||
|
||||
enum { ILLEGAL_RPS = 0xFF };
|
||||
enum { DR_PAGE_EU868 = 0x00 };
|
||||
enum { DR_PAGE_US915 = 0x10 };
|
||||
|
||||
// Global maximum frame length
|
||||
enum { STD_PREAMBLE_LEN = 8 };
|
||||
@ -74,86 +73,123 @@ enum { BCN_RESERVE_us = 2120000 };
|
||||
enum { BCN_GUARD_us = 3000000 };
|
||||
enum { BCN_SLOT_SPAN_us = 30000 };
|
||||
|
||||
// there are exactly 16 datarates
|
||||
enum _dr_code_t {
|
||||
LORAWAN_DR0 = 0,
|
||||
LORAWAN_DR1,
|
||||
LORAWAN_DR2,
|
||||
LORAWAN_DR3,
|
||||
LORAWAN_DR4,
|
||||
LORAWAN_DR5,
|
||||
LORAWAN_DR6,
|
||||
LORAWAN_DR7,
|
||||
LORAWAN_DR8,
|
||||
LORAWAN_DR9,
|
||||
LORAWAN_DR10,
|
||||
LORAWAN_DR11,
|
||||
LORAWAN_DR12,
|
||||
LORAWAN_DR13,
|
||||
LORAWAN_DR14,
|
||||
LORAWAN_DR15,
|
||||
LORAWAN_DR_LENGTH // 16, for sizing arrays.
|
||||
};
|
||||
|
||||
// post conditions from this block: symbols used by general code that is not
|
||||
// ostensiblly region-specific.
|
||||
// DR_DFLTMIN must be defined as a suitable substititute value if we get a bogus DR
|
||||
// DR_PAGE is used only for a non-supported debug system, but should be defined.
|
||||
// CHNL_DNW2 is the channel to be used for RX2
|
||||
// FREQ_DNW2 is the frequency to be used for RX2
|
||||
// DR_DNW2 is the data-rate to be used for RX2
|
||||
//
|
||||
// The Class B stuff is untested and definitely wrong in parts for LoRaWAN 1.02
|
||||
// CHNL_PING is the channel to be used for pinging.
|
||||
// FREQ_PING is the default ping channel frequency
|
||||
// DR_PING is the data-rate to be used for pings.
|
||||
// CHNL_BCN is the channel to be used for the beacon (or perhaps the start chan)
|
||||
// FREQ_BCN is the frequency to be used for the beacon
|
||||
// DR_BCN is the datarate to be used for the beacon
|
||||
// AIRTIME_BCN is the airtime for the beacon
|
||||
|
||||
|
||||
|
||||
#if defined(CFG_eu868) // ==============================================
|
||||
|
||||
enum _dr_eu868_t { DR_SF12=0, DR_SF11, DR_SF10, DR_SF9, DR_SF8, DR_SF7, DR_SF7B, DR_FSK, DR_NONE };
|
||||
enum { DR_DFLTMIN = DR_SF7 };
|
||||
#include "lorabase_eu868.h"
|
||||
|
||||
// per 2.1.3: not implemented
|
||||
#define LMIC_ENABLE_TxParamSetupReq 0
|
||||
|
||||
enum { DR_DFLTMIN = EU868_DR_SF7 }; // DR5
|
||||
// DR_PAGE is a debugging parameter
|
||||
enum { DR_PAGE = DR_PAGE_EU868 };
|
||||
|
||||
// Default frequency plan for EU 868MHz ISM band
|
||||
// Bands:
|
||||
// g1 : 1% 14dBm
|
||||
// g2 : 0.1% 14dBm
|
||||
// g3 : 10% 27dBm
|
||||
// freq band datarates
|
||||
enum { EU868_F1 = 868100000, // g1 SF7-12
|
||||
EU868_F2 = 868300000, // g1 SF7-12 FSK SF7/250
|
||||
EU868_F3 = 868500000, // g1 SF7-12
|
||||
EU868_F4 = 868850000, // g2 SF7-12
|
||||
EU868_F5 = 869050000, // g2 SF7-12
|
||||
EU868_F6 = 869525000, // g3 SF7-12
|
||||
EU868_J4 = 864100000, // g2 SF7-12 used during join
|
||||
EU868_J5 = 864300000, // g2 SF7-12 ditto
|
||||
EU868_J6 = 864500000, // g2 SF7-12 ditto
|
||||
};
|
||||
enum { EU868_FREQ_MIN = 863000000,
|
||||
EU868_FREQ_MAX = 870000000 };
|
||||
|
||||
enum { CHNL_PING = 5 };
|
||||
enum { FREQ_PING = EU868_F6 }; // default ping freq
|
||||
enum { DR_PING = DR_SF9 }; // default ping DR
|
||||
enum { CHNL_DNW2 = 5 };
|
||||
enum { FREQ_DNW2 = EU868_F6 };
|
||||
enum { DR_DNW2 = DR_SF12 };
|
||||
enum { CHNL_BCN = 5 };
|
||||
enum { FREQ_BCN = EU868_F6 };
|
||||
enum { DR_BCN = DR_SF9 };
|
||||
enum { AIRTIME_BCN = 144384 }; // micros
|
||||
//enum { CHNL_PING = 5 };
|
||||
enum { FREQ_PING = EU868_F6 }; // default ping freq
|
||||
enum { DR_PING = EU868_DR_SF9 }; // default ping DR
|
||||
//enum { CHNL_DNW2 = 5 };
|
||||
enum { FREQ_DNW2 = EU868_F6 };
|
||||
enum { DR_DNW2 = EU868_DR_SF12 };
|
||||
enum { CHNL_BCN = 5 };
|
||||
enum { FREQ_BCN = EU868_F6 };
|
||||
enum { DR_BCN = EU868_DR_SF9 };
|
||||
enum { AIRTIME_BCN = 144384 }; // micros
|
||||
enum { LMIC_REGION_EIRP = EU868_LMIC_REGION_EIRP }; // region uses EIRP
|
||||
|
||||
enum {
|
||||
// Beacon frame format EU SF9
|
||||
OFF_BCN_NETID = 0,
|
||||
OFF_BCN_TIME = 3,
|
||||
OFF_BCN_CRC1 = 7,
|
||||
OFF_BCN_INFO = 8,
|
||||
OFF_BCN_LAT = 9,
|
||||
OFF_BCN_LON = 12,
|
||||
OFF_BCN_CRC2 = 15,
|
||||
LEN_BCN = 17
|
||||
// Beacon frame format EU SF9
|
||||
OFF_BCN_NETID = 0,
|
||||
OFF_BCN_TIME = 3,
|
||||
OFF_BCN_CRC1 = 7,
|
||||
OFF_BCN_INFO = 8,
|
||||
OFF_BCN_LAT = 9,
|
||||
OFF_BCN_LON = 12,
|
||||
OFF_BCN_CRC2 = 15,
|
||||
LEN_BCN = 17
|
||||
};
|
||||
|
||||
// for backwards compatibility. This must match _dr_eu868_t
|
||||
# if LMIC_DR_LEGACY
|
||||
enum _dr_configured_t {
|
||||
DR_SF12 = EU868_DR_SF12,
|
||||
DR_SF11 = EU868_DR_SF11,
|
||||
DR_SF10 = EU868_DR_SF10,
|
||||
DR_SF9 = EU868_DR_SF9,
|
||||
DR_SF8 = EU868_DR_SF8,
|
||||
DR_SF7 = EU868_DR_SF7,
|
||||
DR_SF7B = EU868_DR_SF7B,
|
||||
DR_FSK = EU868_DR_FSK,
|
||||
DR_NONE = EU868_DR_NONE
|
||||
};
|
||||
# endif // LMIC_DR_LEGACY
|
||||
|
||||
#elif defined(CFG_us915) // =========================================
|
||||
|
||||
enum _dr_us915_t { DR_SF10=0, DR_SF9, DR_SF8, DR_SF7, DR_SF8C, DR_NONE,
|
||||
// Devices behind a router:
|
||||
DR_SF12CR=8, DR_SF11CR, DR_SF10CR, DR_SF9CR, DR_SF8CR, DR_SF7CR };
|
||||
enum { DR_DFLTMIN = DR_SF8C };
|
||||
#include "lorabase_us915.h"
|
||||
|
||||
// per 2.2.3: not implemented
|
||||
#define LMIC_ENABLE_TxParamSetupReq 0
|
||||
|
||||
enum { DR_DFLTMIN = US915_DR_SF7 }; // DR5
|
||||
|
||||
// DR_PAGE is a debugging parameter; it must be defined but it has no use in arduino-lmic
|
||||
enum { DR_PAGE = DR_PAGE_US915 };
|
||||
|
||||
// Default frequency plan for US 915MHz
|
||||
enum { US915_125kHz_UPFBASE = 902300000,
|
||||
US915_125kHz_UPFSTEP = 200000,
|
||||
US915_500kHz_UPFBASE = 903000000,
|
||||
US915_500kHz_UPFSTEP = 1600000,
|
||||
US915_500kHz_DNFBASE = 923300000,
|
||||
US915_500kHz_DNFSTEP = 600000
|
||||
};
|
||||
enum { US915_FREQ_MIN = 902000000,
|
||||
US915_FREQ_MAX = 928000000 };
|
||||
|
||||
enum { CHNL_PING = 0 }; // used only for default init of state (follows beacon - rotating)
|
||||
enum { FREQ_PING = US915_500kHz_DNFBASE + CHNL_PING*US915_500kHz_DNFSTEP }; // default ping freq
|
||||
enum { DR_PING = DR_SF10CR }; // default ping DR
|
||||
enum { CHNL_DNW2 = 0 };
|
||||
enum { FREQ_DNW2 = US915_500kHz_DNFBASE + CHNL_DNW2*US915_500kHz_DNFSTEP };
|
||||
enum { DR_DNW2 = DR_SF12CR };
|
||||
//enum { CHNL_PING = 0 }; // used only for default init of state (follows beacon - rotating)
|
||||
enum { FREQ_PING = US915_500kHz_DNFBASE + 0*US915_500kHz_DNFSTEP }; // default ping freq
|
||||
enum { DR_PING = US915_DR_SF10CR }; // default ping DR
|
||||
//enum { CHNL_DNW2 = 0 };
|
||||
enum { FREQ_DNW2 = US915_500kHz_DNFBASE + 0*US915_500kHz_DNFSTEP };
|
||||
enum { DR_DNW2 = US915_DR_SF12CR };
|
||||
enum { CHNL_BCN = 0 }; // used only for default init of state (rotating beacon scheme)
|
||||
enum { DR_BCN = DR_SF10CR };
|
||||
enum { DR_BCN = US915_DR_SF12CR };
|
||||
// TODO(tmm@mcci.com): check this, as beacon DR was SF10 in IBM code.
|
||||
enum { AIRTIME_BCN = 72192 }; // micros
|
||||
enum { LMIC_REGION_EIRP = US915_LMIC_REGION_EIRP }; // region uses EIRP
|
||||
|
||||
enum {
|
||||
// Beacon frame format US SF10
|
||||
OFF_BCN_NETID = 0,
|
||||
OFF_BCN_NETID = 0,
|
||||
OFF_BCN_TIME = 3,
|
||||
OFF_BCN_CRC1 = 7,
|
||||
OFF_BCN_INFO = 9,
|
||||
@ -164,6 +200,172 @@ enum {
|
||||
LEN_BCN = 19
|
||||
};
|
||||
|
||||
# if LMIC_DR_LEGACY
|
||||
enum _dr_configured_t {
|
||||
DR_SF10 = US915_DR_SF10,
|
||||
DR_SF9 = US915_DR_SF9,
|
||||
DR_SF8 = US915_DR_SF8,
|
||||
DR_SF7 = US915_DR_SF7,
|
||||
DR_SF8C = US915_DR_SF8C,
|
||||
DR_NONE = US915_DR_NONE,
|
||||
DR_SF12CR = US915_DR_SF12CR,
|
||||
DR_SF11CR = US915_DR_SF11CR,
|
||||
DR_SF10CR = US915_DR_SF10CR,
|
||||
DR_SF9CR = US915_DR_SF9CR,
|
||||
DR_SF8CR = US915_DR_SF8CR,
|
||||
DR_SF7CR = US915_DR_SF7CR
|
||||
};
|
||||
# endif // LMIC_DR_LEGACY
|
||||
|
||||
#elif defined(CFG_au921) // =========================================
|
||||
|
||||
#include "lorabase_au921.h"
|
||||
|
||||
// per 2.5.3: not implemented
|
||||
#define LMIC_ENABLE_TxParamSetupReq 0
|
||||
|
||||
enum { DR_DFLTMIN = AU921_DR_SF7 }; // DR5
|
||||
|
||||
// DR_PAGE is a debugging parameter; it must be defined but it has no use in arduino-lmic
|
||||
enum { DR_PAGE = DR_PAGE_AU921 };
|
||||
|
||||
//enum { CHNL_PING = 0 }; // used only for default init of state (follows beacon - rotating)
|
||||
enum { FREQ_PING = AU921_500kHz_DNFBASE + 0*AU921_500kHz_DNFSTEP }; // default ping freq
|
||||
enum { DR_PING = AU921_DR_SF10CR }; // default ping DR
|
||||
//enum { CHNL_DNW2 = 0 };
|
||||
enum { FREQ_DNW2 = AU921_500kHz_DNFBASE + 0*AU921_500kHz_DNFSTEP };
|
||||
enum { DR_DNW2 = AU921_DR_SF12CR }; // DR8
|
||||
enum { CHNL_BCN = 0 }; // used only for default init of state (rotating beacon scheme)
|
||||
enum { DR_BCN = AU921_DR_SF10CR };
|
||||
enum { AIRTIME_BCN = 72192 }; // micros ... TODO(tmm@mcci.com) check.
|
||||
enum { LMIC_REGION_EIRP = AU921_LMIC_REGION_EIRP }; // region uses EIRP
|
||||
|
||||
enum {
|
||||
// Beacon frame format AU DR10/SF10 500kHz
|
||||
OFF_BCN_NETID = 0,
|
||||
OFF_BCN_TIME = 3,
|
||||
OFF_BCN_CRC1 = 7,
|
||||
OFF_BCN_INFO = 9,
|
||||
OFF_BCN_LAT = 10,
|
||||
OFF_BCN_LON = 13,
|
||||
OFF_BCN_RFU1 = 16,
|
||||
OFF_BCN_CRC2 = 17,
|
||||
LEN_BCN = 19
|
||||
};
|
||||
|
||||
# if LMIC_DR_LEGACY
|
||||
enum _dr_configured_t {
|
||||
DR_SF12 = AU921_DR_SF12,
|
||||
DR_SF11 = AU921_DR_SF11,
|
||||
DR_SF10 = AU921_DR_SF10,
|
||||
DR_SF9 = AU921_DR_SF9,
|
||||
DR_SF8 = AU921_DR_SF8,
|
||||
DR_SF7 = AU921_DR_SF7,
|
||||
DR_SF8C = AU921_DR_SF8C,
|
||||
DR_NONE = AU921_DR_NONE,
|
||||
DR_SF12CR = AU921_DR_SF12CR,
|
||||
DR_SF11CR = AU921_DR_SF11CR,
|
||||
DR_SF10CR = AU921_DR_SF10CR,
|
||||
DR_SF9CR = AU921_DR_SF9CR,
|
||||
DR_SF8CR = AU921_DR_SF8CR,
|
||||
DR_SF7CR = AU921_DR_SF7CR
|
||||
};
|
||||
# endif // LMIC_DR_LEGACY
|
||||
|
||||
#elif defined(CFG_as923) // ==============================================
|
||||
|
||||
#include "lorabase_as923.h"
|
||||
|
||||
// per 2.7.3: must be implemented
|
||||
#define LMIC_ENABLE_TxParamSetupReq 1
|
||||
|
||||
enum { DR_DFLTMIN = AS923_DR_SF10 }; // DR2
|
||||
// DR_PAGE is a debugging parameter
|
||||
enum { DR_PAGE = DR_PAGE_AS923 };
|
||||
|
||||
enum { FREQ_PING = AS923_F2 }; // default ping freq
|
||||
enum { DR_PING = AS923_DR_SF9 }; // default ping DR: DR3
|
||||
enum { FREQ_DNW2 = AS923_FDOWN };
|
||||
enum { DR_DNW2 = AS923_DR_SF10 };
|
||||
enum { CHNL_BCN = 5 };
|
||||
enum { FREQ_BCN = AS923_FBCN };
|
||||
enum { DR_BCN = AS923_DR_SF9 };
|
||||
enum { AIRTIME_BCN = 144384 }; // micros
|
||||
enum { LMIC_REGION_EIRP = AS923_LMIC_REGION_EIRP }; // region uses EIRP
|
||||
|
||||
enum {
|
||||
// Beacon frame format AS SF9
|
||||
OFF_BCN_NETID = 0,
|
||||
OFF_BCN_TIME = 2,
|
||||
OFF_BCN_CRC1 = 6,
|
||||
OFF_BCN_INFO = 8,
|
||||
OFF_BCN_LAT = 9,
|
||||
OFF_BCN_LON = 12,
|
||||
OFF_BCN_CRC2 = 15,
|
||||
LEN_BCN = 17
|
||||
};
|
||||
|
||||
# if LMIC_DR_LEGACY
|
||||
enum _dr_configured_t {
|
||||
DR_SF12 = AS923_DR_SF12,
|
||||
DR_SF11 = AS923_DR_SF11,
|
||||
DR_SF10 = AS923_DR_SF10,
|
||||
DR_SF9 = AS923_DR_SF9,
|
||||
DR_SF8 = AS923_DR_SF8,
|
||||
DR_SF7 = AS923_DR_SF7,
|
||||
DR_SF7B = AS923_DR_SF7B,
|
||||
DR_FSK = AS923_DR_FSK,
|
||||
DR_NONE = AS923_DR_NONE
|
||||
};
|
||||
# endif // LMIC_DR_LEGACY
|
||||
|
||||
#elif defined(CFG_in866) // ==============================================
|
||||
|
||||
#include "lorabase_in866.h"
|
||||
|
||||
// per 2.9.3: not implemented
|
||||
#define LMIC_ENABLE_TxParamSetupReq 0
|
||||
|
||||
enum { DR_DFLTMIN = IN866_DR_SF7 }; // DR5
|
||||
enum { DR_PAGE = DR_PAGE_IN866 }; // DR_PAGE is a debugging parameter
|
||||
|
||||
enum { FREQ_PING = IN866_FB }; // default ping freq
|
||||
enum { DR_PING = IN866_DR_SF8 }; // default ping DR
|
||||
enum { FREQ_DNW2 = IN866_FB };
|
||||
enum { DR_DNW2 = IN866_DR_SF10 };
|
||||
enum { CHNL_BCN = 5 };
|
||||
enum { FREQ_BCN = IN866_FB };
|
||||
enum { DR_BCN = IN866_DR_SF8 };
|
||||
enum { AIRTIME_BCN = 144384 }; // micros
|
||||
enum { LMIC_REGION_EIRP = IN866_LMIC_REGION_EIRP }; // region uses EIRP
|
||||
|
||||
enum {
|
||||
// Beacon frame format IN SF9
|
||||
OFF_BCN_NETID = 0,
|
||||
OFF_BCN_TIME = 1,
|
||||
OFF_BCN_CRC1 = 5,
|
||||
OFF_BCN_INFO = 7,
|
||||
OFF_BCN_LAT = 8,
|
||||
OFF_BCN_LON = 11,
|
||||
OFF_BCN_CRC2 = 17,
|
||||
LEN_BCN = 19
|
||||
};
|
||||
|
||||
# if LMIC_DR_LEGACY
|
||||
enum _dr_configured_t {
|
||||
DR_SF12 = IN866_DR_SF12, // DR0
|
||||
DR_SF11 = IN866_DR_SF11, // DR1
|
||||
DR_SF10 = IN866_DR_SF10, // DR2
|
||||
DR_SF9 = IN866_DR_SF9, // DR3
|
||||
DR_SF8 = IN866_DR_SF8, // DR4
|
||||
DR_SF7 = IN866_DR_SF7, // DR5
|
||||
DR_FSK = IN866_DR_FSK, // DR7
|
||||
DR_NONE = IN866_DR_NONE
|
||||
};
|
||||
# endif // LMIC_DR_LEGACY
|
||||
|
||||
#else
|
||||
# error Unsupported configuration setting
|
||||
#endif // ===================================================
|
||||
|
||||
enum {
|
||||
@ -238,12 +440,16 @@ enum {
|
||||
// MAC uplink commands downwlink too
|
||||
enum {
|
||||
// Class A
|
||||
MCMD_LCHK_REQ = 0x02, // - link check request : -
|
||||
MCMD_LADR_ANS = 0x03, // - link ADR answer : u1:7-3:RFU, 3/2/1: pow/DR/Ch ACK
|
||||
MCMD_DCAP_ANS = 0x04, // - duty cycle answer : -
|
||||
MCMD_DN2P_ANS = 0x05, // - 2nd DN slot status : u1:7-2:RFU 1/0:datarate/channel ack
|
||||
MCMD_DEVS_ANS = 0x06, // - device status ans : u1:battery 0,1-254,255=?, u1:7-6:RFU,5-0:margin(-32..31)
|
||||
MCMD_SNCH_ANS = 0x07, // - set new channel : u1: 7-2=RFU, 1/0:DR/freq ACK
|
||||
MCMD_LCHK_REQ = 0x02, // - LinkCheckReq : -
|
||||
MCMD_LADR_ANS = 0x03, // - LinkADRAnd : u1:7-3:RFU, 3/2/1: pow/DR/Ch ACK
|
||||
MCMD_DCAP_ANS = 0x04, // - DutyCycleAns : -
|
||||
MCMD_DN2P_ANS = 0x05, // - RxParamSetupAns : u1:7-2:RFU 1/0:datarate/channel ack
|
||||
MCMD_DEVS_ANS = 0x06, // - DevStatusAns : u1:battery 0,1-254,255=?, u1:7-6:RFU,5-0:margin(-32..31)
|
||||
MCMD_SNCH_ANS = 0x07, // - NewChannelAns : u1: 7-2=RFU, 1/0:DR/freq ACK
|
||||
MCMD_RXTimingSetupAns = 0x08, // : -
|
||||
MCMD_TxParamSetupAns = 0x09, // : -
|
||||
MCMD_DIChannelAns = 0x0A, // : u1: [7-2]:RFU 1:exists 0:OK
|
||||
|
||||
// Class B
|
||||
MCMD_PING_IND = 0x10, // - pingability indic : u1: 7=RFU, 6-4:interval, 3-0:datarate
|
||||
MCMD_PING_ANS = 0x11, // - ack ping freq : u1: 7-1:RFU, 0:freq ok
|
||||
@ -253,12 +459,16 @@ enum {
|
||||
// MAC downlink commands
|
||||
enum {
|
||||
// Class A
|
||||
MCMD_LCHK_ANS = 0x02, // link check answer : u1:margin 0-254,255=unknown margin / u1:gwcnt
|
||||
MCMD_LADR_REQ = 0x03, // link ADR request : u1:DR/TXPow, u2:chmask, u1:chpage/repeat
|
||||
MCMD_DCAP_REQ = 0x04, // duty cycle cap : u1:255 dead [7-4]:RFU, [3-0]:cap 2^-k
|
||||
MCMD_DN2P_SET = 0x05, // 2nd DN window param: u1:7-4:RFU/3-0:datarate, u3:freq
|
||||
MCMD_DEVS_REQ = 0x06, // device status req : -
|
||||
MCMD_SNCH_REQ = 0x07, // set new channel : u1:chidx, u3:freq, u1:DRrange
|
||||
MCMD_LCHK_ANS = 0x02, // LinkCheckAns : u1:margin 0-254,255=unknown margin / u1:gwcnt LinkCheckReq
|
||||
MCMD_LADR_REQ = 0x03, // LinkADRReq : u1:DR/TXPow, u2:chmask, u1:chpage/repeat
|
||||
MCMD_DCAP_REQ = 0x04, // DutyCycleReq : u1:255 dead [7-4]:RFU, [3-0]:cap 2^-k
|
||||
MCMD_DN2P_SET = 0x05, // RXParamSetupReq : u1:7-4:RFU/3-0:datarate, u3:freq
|
||||
MCMD_DEVS_REQ = 0x06, // DevStatusReq : -
|
||||
MCMD_SNCH_REQ = 0x07, // NewChannelReq : u1:chidx, u3:freq, u1:DRrange
|
||||
MCMD_RXTimingSetupReq = 0x08, // : u1: [7-4]:RFU [3-0]: Delay 1-15s (0 => 1)
|
||||
MCMD_TxParamSetupReq = 0x09, // : u1: [7-6]:RFU [5:4]: dl dwell/ul dwell [3:0] max EIRP
|
||||
MCMD_DIChannelReq = 0x0A, // : u1: channel, u3: frequency
|
||||
|
||||
// Class B
|
||||
MCMD_PING_SET = 0x11, // set ping freq : u3: freq
|
||||
MCMD_BCNI_ANS = 0x12, // next beacon start : u2: delay(in TUNIT millis), u1:channel
|
||||
@ -274,7 +484,8 @@ enum {
|
||||
MCMD_LADR_ANS_CHACK = 0x01, // 0=unknown channel enabled
|
||||
};
|
||||
enum {
|
||||
MCMD_DN2P_ANS_RFU = 0xFC, // RFU bits
|
||||
MCMD_DN2P_ANS_RFU = 0xF8, // RFU bits
|
||||
MCMD_DN2P_ANS_RX1DrOffsetAck = 0x04, // 0=dr2 not allowed
|
||||
MCMD_DN2P_ANS_DRACK = 0x02, // 0=unknown data rate
|
||||
MCMD_DN2P_ANS_CHACK = 0x01, // 0=unknown channel enabled
|
||||
};
|
||||
@ -297,8 +508,10 @@ enum {
|
||||
|
||||
// Bit fields byte#3 of MCMD_LADR_REQ payload
|
||||
enum {
|
||||
MCMD_LADR_CHP_USLIKE_SPECIAL = 0x50, // first special for us-like
|
||||
MCMD_LADR_CHP_BANK = 0x50, // special: bits are banks.
|
||||
MCMD_LADR_CHP_125ON = 0x60, // special channel page enable, bits applied to 64..71
|
||||
MCMD_LADR_CHP_125OFF = 0x70, // ditto
|
||||
MCMD_LADR_CHP_125OFF = 0x70, // special channel page: disble 125K, bits apply to 64..71
|
||||
MCMD_LADR_N3RFU_MASK = 0x80,
|
||||
MCMD_LADR_CHPAGE_MASK = 0xF0,
|
||||
MCMD_LADR_REPEAT_MASK = 0x0F,
|
||||
@ -311,49 +524,59 @@ enum {
|
||||
MCMD_LADR_POW_MASK = 0x0F,
|
||||
MCMD_LADR_DR_SHIFT = 4,
|
||||
MCMD_LADR_POW_SHIFT = 0,
|
||||
#if defined(CFG_eu868)
|
||||
MCMD_LADR_SF12 = DR_SF12<<4,
|
||||
MCMD_LADR_SF11 = DR_SF11<<4,
|
||||
MCMD_LADR_SF10 = DR_SF10<<4,
|
||||
MCMD_LADR_SF9 = DR_SF9 <<4,
|
||||
MCMD_LADR_SF8 = DR_SF8 <<4,
|
||||
MCMD_LADR_SF7 = DR_SF7 <<4,
|
||||
MCMD_LADR_SF7B = DR_SF7B<<4,
|
||||
MCMD_LADR_FSK = DR_FSK <<4,
|
||||
#if defined(CFG_eu868) // TODO(tmm@mcci.com): complete refactor.
|
||||
EU868_MCMD_LADR_SF12 = EU868_DR_SF12<<4,
|
||||
EU868_MCMD_LADR_SF11 = EU868_DR_SF11<<4,
|
||||
EU868_MCMD_LADR_SF10 = EU868_DR_SF10<<4,
|
||||
EU868_MCMD_LADR_SF9 = EU868_DR_SF9 <<4,
|
||||
EU868_MCMD_LADR_SF8 = EU868_DR_SF8 <<4,
|
||||
EU868_MCMD_LADR_SF7 = EU868_DR_SF7 <<4,
|
||||
EU868_MCMD_LADR_SF7B = EU868_DR_SF7B<<4,
|
||||
EU868_MCMD_LADR_FSK = EU868_DR_FSK <<4,
|
||||
|
||||
MCMD_LADR_20dBm = 0,
|
||||
MCMD_LADR_14dBm = 1,
|
||||
MCMD_LADR_11dBm = 2,
|
||||
MCMD_LADR_8dBm = 3,
|
||||
MCMD_LADR_5dBm = 4,
|
||||
MCMD_LADR_2dBm = 5,
|
||||
EU868_MCMD_LADR_20dBm = 0,
|
||||
EU868_MCMD_LADR_14dBm = 1,
|
||||
EU868_MCMD_LADR_11dBm = 2,
|
||||
EU868_MCMD_LADR_8dBm = 3,
|
||||
EU868_MCMD_LADR_5dBm = 4,
|
||||
EU868_MCMD_LADR_2dBm = 5,
|
||||
#elif defined(CFG_us915)
|
||||
MCMD_LADR_SF10 = DR_SF10<<4,
|
||||
MCMD_LADR_SF9 = DR_SF9 <<4,
|
||||
MCMD_LADR_SF8 = DR_SF8 <<4,
|
||||
MCMD_LADR_SF7 = DR_SF7 <<4,
|
||||
MCMD_LADR_SF8C = DR_SF8C<<4,
|
||||
MCMD_LADR_SF12CR = DR_SF12CR<<4,
|
||||
MCMD_LADR_SF11CR = DR_SF11CR<<4,
|
||||
MCMD_LADR_SF10CR = DR_SF10CR<<4,
|
||||
MCMD_LADR_SF9CR = DR_SF9CR<<4,
|
||||
MCMD_LADR_SF8CR = DR_SF8CR<<4,
|
||||
MCMD_LADR_SF7CR = DR_SF7CR<<4,
|
||||
US915_MCMD_LADR_SF10 = US915_DR_SF10<<4,
|
||||
US915_MCMD_LADR_SF9 = US915_DR_SF9 <<4,
|
||||
US915_MCMD_LADR_SF8 = US915_DR_SF8 <<4,
|
||||
US915_MCMD_LADR_SF7 = US915_DR_SF7 <<4,
|
||||
US915_MCMD_LADR_SF8C = US915_DR_SF8C<<4,
|
||||
US915_MCMD_LADR_SF12CR = US915_DR_SF12CR<<4,
|
||||
US915_MCMD_LADR_SF11CR = US915_DR_SF11CR<<4,
|
||||
US915_MCMD_LADR_SF10CR = US915_DR_SF10CR<<4,
|
||||
US915_MCMD_LADR_SF9CR = US915_DR_SF9CR<<4,
|
||||
US915_MCMD_LADR_SF8CR = US915_DR_SF8CR<<4,
|
||||
US915_MCMD_LADR_SF7CR = US915_DR_SF7CR<<4,
|
||||
|
||||
MCMD_LADR_30dBm = 0,
|
||||
MCMD_LADR_28dBm = 1,
|
||||
MCMD_LADR_26dBm = 2,
|
||||
MCMD_LADR_24dBm = 3,
|
||||
MCMD_LADR_22dBm = 4,
|
||||
MCMD_LADR_20dBm = 5,
|
||||
MCMD_LADR_18dBm = 6,
|
||||
MCMD_LADR_16dBm = 7,
|
||||
MCMD_LADR_14dBm = 8,
|
||||
MCMD_LADR_12dBm = 9,
|
||||
MCMD_LADR_10dBm = 10
|
||||
US915_MCMD_LADR_30dBm = 0,
|
||||
US915_MCMD_LADR_28dBm = 1,
|
||||
US915_MCMD_LADR_26dBm = 2,
|
||||
US915_MCMD_LADR_24dBm = 3,
|
||||
US915_MCMD_LADR_22dBm = 4,
|
||||
US915_MCMD_LADR_20dBm = 5,
|
||||
US915_MCMD_LADR_18dBm = 6,
|
||||
US915_MCMD_LADR_16dBm = 7,
|
||||
US915_MCMD_LADR_14dBm = 8,
|
||||
US915_MCMD_LADR_12dBm = 9,
|
||||
US915_MCMD_LADR_10dBm = 10
|
||||
#endif
|
||||
};
|
||||
|
||||
// bit fields of the TxParam request
|
||||
enum {
|
||||
MCMD_TxParam_RxDWELL_SHIFT = 5,
|
||||
MCMD_TxParam_RxDWELL_MASK = 1 << MCMD_TxParam_RxDWELL_SHIFT,
|
||||
MCMD_TxParam_TxDWELL_SHIFT = 4,
|
||||
MCMD_TxParam_TxDWELL_MASK = 1 << MCMD_TxParam_TxDWELL_SHIFT,
|
||||
MCMD_TxParam_MaxEIRP_SHIFT = 0,
|
||||
MCMD_TxParam_MaxEIRP_MASK = 0xF << MCMD_TxParam_MaxEIRP_SHIFT,
|
||||
};
|
||||
|
||||
// Device address
|
||||
typedef u4_t devaddr_t;
|
||||
|
||||
@ -374,18 +597,19 @@ inline rps_t makeRps (sf_t sf, bw_t bw, cr_t cr, int ih, int nocrc) {
|
||||
return sf | (bw<<3) | (cr<<5) | (nocrc?(1<<7):0) | ((ih&0xFF)<<8);
|
||||
}
|
||||
#define MAKERPS(sf,bw,cr,ih,nocrc) ((rps_t)((sf) | ((bw)<<3) | ((cr)<<5) | ((nocrc)?(1<<7):0) | ((ih&0xFF)<<8)))
|
||||
// Two frames with params r1/r2 would interfere on air: same SFx + BWx
|
||||
// Two frames with params r1/r2 would interfere on air: same SFx + BWx
|
||||
inline int sameSfBw(rps_t r1, rps_t r2) { return ((r1^r2)&0x1F) == 0; }
|
||||
|
||||
extern const u1_t _DR2RPS_CRC[];
|
||||
inline rps_t updr2rps (dr_t dr) { return (rps_t)_DR2RPS_CRC[dr+1]; }
|
||||
extern CONST_TABLE(u1_t, _DR2RPS_CRC)[];
|
||||
inline rps_t updr2rps (dr_t dr) { return (rps_t)TABLE_GET_U1(_DR2RPS_CRC, dr+1); }
|
||||
inline rps_t dndr2rps (dr_t dr) { return setNocrc(updr2rps(dr),1); }
|
||||
inline int isFasterDR (dr_t dr1, dr_t dr2) { return dr1 > dr2; }
|
||||
inline int isSlowerDR (dr_t dr1, dr_t dr2) { return dr1 < dr2; }
|
||||
inline dr_t incDR (dr_t dr) { return _DR2RPS_CRC[dr+2]==ILLEGAL_RPS ? dr : (dr_t)(dr+1); } // increase data rate
|
||||
inline dr_t decDR (dr_t dr) { return _DR2RPS_CRC[dr ]==ILLEGAL_RPS ? dr : (dr_t)(dr-1); } // decrease data rate
|
||||
inline dr_t assertDR (dr_t dr) { return _DR2RPS_CRC[dr+1]==ILLEGAL_RPS ? (dr_t)DR_DFLTMIN : dr; } // force into a valid DR
|
||||
inline bit_t validDR (dr_t dr) { return _DR2RPS_CRC[dr+1]!=ILLEGAL_RPS; } // in range
|
||||
inline dr_t incDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+2)==ILLEGAL_RPS ? dr : (dr_t)(dr+1); } // increase data rate
|
||||
inline dr_t decDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr )==ILLEGAL_RPS ? dr : (dr_t)(dr-1); } // decrease data rate
|
||||
// ttn-esp32 change: remove unused function creating warning
|
||||
//inline dr_t assertDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+1)==ILLEGAL_RPS ? DR_DFLTMIN : dr; } // force into a valid DR
|
||||
inline bit_t validDR (dr_t dr) { return TABLE_GET_U1(_DR2RPS_CRC, dr+1)!=ILLEGAL_RPS; } // in range
|
||||
inline dr_t lowerDR (dr_t dr, u1_t n) { while(n--){dr=decDR(dr);} return dr; } // decrease data rate by n steps
|
||||
|
||||
//
|
||||
@ -393,8 +617,6 @@ inline dr_t lowerDR (dr_t dr, u1_t n) { while(n--){dr=decDR(dr);} return dr; }
|
||||
// ================================================================================
|
||||
|
||||
|
||||
// Convert between dBm values and power codes (MCMD_LADR_XdBm)
|
||||
s1_t pow2dBm (u1_t mcmd_ladr_p1);
|
||||
// Calculate airtime
|
||||
ostime_t calcAirTime (rps_t rps, u1_t plen);
|
||||
// Sensitivity at given SF/BW
|
||||
|
96
src/lmic/lorabase_as923.h
Executable file
96
src/lmic/lorabase_as923.h
Executable file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2017 MCCI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lorabase_as923_h_
|
||||
#define _lorabase_as923_h_
|
||||
|
||||
#ifndef _LMIC_CONFIG_PRECONDITIONS_H_
|
||||
# include "lmic_config_preconditions.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| Basic definitions for AS923 (always in scope)
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
enum _dr_as923_t {
|
||||
AS923_DR_SF12 = 0,
|
||||
AS923_DR_SF11,
|
||||
AS923_DR_SF10,
|
||||
AS923_DR_SF9,
|
||||
AS923_DR_SF8,
|
||||
AS923_DR_SF7,
|
||||
AS923_DR_SF7B,
|
||||
AS923_DR_FSK,
|
||||
AS923_DR_NONE
|
||||
};
|
||||
|
||||
// Bands:
|
||||
// g1 : 1% 16dBm
|
||||
// freq band datarates
|
||||
enum {
|
||||
AS923_F1 = 923200000, // g1 SF7-12
|
||||
AS923_F2 = 923400000, // g1 SF7-12
|
||||
AS923_FDOWN = 923200000, // (RX2 freq, DR2)
|
||||
AS923_FBCN = 923400000, // default BCN, DR3
|
||||
AS923_FPING = 923400000, // default ping, DR3
|
||||
};
|
||||
enum {
|
||||
AS923_FREQ_MIN = 915000000,
|
||||
AS923_FREQ_MAX = 928000000
|
||||
};
|
||||
enum {
|
||||
AS923_TX_EIRP_MAX_DBM = 16 // 16 dBm
|
||||
};
|
||||
enum { DR_PAGE_AS923 = 0x10 * (LMIC_REGION_as923 - 1) };
|
||||
|
||||
enum { AS923_LMIC_REGION_EIRP = 1 }; // region uses EIRP
|
||||
|
||||
enum { AS923JP_LBT_US = 5000 }; // microseconds of LBT time -- 5000 ==>
|
||||
// 5 ms. We use us rather than ms for
|
||||
// future 128us support, and just for
|
||||
// backward compatibility -- there
|
||||
// is code that uses the _US constant,
|
||||
// and it's awkward to break it.
|
||||
|
||||
enum { AS923JP_LBT_DB_MAX = -80 }; // maximum channel strength in dB; if TX
|
||||
// we measure more than this, we don't tx.
|
||||
|
||||
// AS923 v1.1, all channels face a 1% duty cycle. So this will have to change
|
||||
// in the future via a config. But this code base needs major changes for
|
||||
// v1.1 in any case.
|
||||
enum { AS923_V102_TX_CAP = 100 }; // v1.0.2 allows 100%
|
||||
|
||||
#ifndef AS923_TX_CAP
|
||||
# define AS923_TX_CAP AS923_V102_TX_CAP
|
||||
#endif
|
||||
|
||||
#endif /* _lorabase_as923_h_ */
|
84
src/lmic/lorabase_au921.h
Executable file
84
src/lmic/lorabase_au921.h
Executable file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2017 MCCI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lorabase_au921_h_
|
||||
#define _lorabase_au921_h_
|
||||
|
||||
#ifndef _LMIC_CONFIG_PRECONDITIONS_H_
|
||||
# include "lmic_config_preconditions.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| Basic definitions for AS921 (always in scope)
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
// Frequency plan for AU 921 MHz
|
||||
enum _dr_as921_t {
|
||||
AU921_DR_SF12 = 0,
|
||||
AU921_DR_SF11,
|
||||
AU921_DR_SF10,
|
||||
AU921_DR_SF9,
|
||||
AU921_DR_SF8,
|
||||
AU921_DR_SF7,
|
||||
AU921_DR_SF8C,
|
||||
AU921_DR_NONE,
|
||||
// Devices behind a router:
|
||||
AU921_DR_SF12CR = 8,
|
||||
AU921_DR_SF11CR,
|
||||
AU921_DR_SF10CR,
|
||||
AU921_DR_SF9CR,
|
||||
AU921_DR_SF8CR,
|
||||
AU921_DR_SF7CR
|
||||
};
|
||||
|
||||
// Default frequency plan for AU 921MHz
|
||||
enum {
|
||||
AU921_125kHz_UPFBASE = 915200000,
|
||||
AU921_125kHz_UPFSTEP = 200000,
|
||||
AU921_500kHz_UPFBASE = 915900000,
|
||||
AU921_500kHz_UPFSTEP = 1600000,
|
||||
AU921_500kHz_DNFBASE = 923300000,
|
||||
AU921_500kHz_DNFSTEP = 600000
|
||||
};
|
||||
enum {
|
||||
AU921_FREQ_MIN = 915000000,
|
||||
AU921_FREQ_MAX = 928000000
|
||||
};
|
||||
enum {
|
||||
AU921_TX_EIRP_MAX_DBM = 30 // 30 dBm
|
||||
};
|
||||
|
||||
enum { DR_PAGE_AU921 = 0x10 * (LMIC_REGION_au921 - 1) };
|
||||
|
||||
enum { AU921_LMIC_REGION_EIRP = 1 }; // region uses EIRP
|
||||
|
||||
#endif /* _lorabase_au921_h_ */
|
92
src/lmic/lorabase_eu868.h
Executable file
92
src/lmic/lorabase_eu868.h
Executable file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2017 MCCI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lorabase_eu868_h_
|
||||
#define _lorabase_eu868_h_
|
||||
|
||||
#ifndef _LMIC_CONFIG_PRECONDITIONS_H_
|
||||
# include "lmic_config_preconditions.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| Basic definitions for EU868 (always in scope)
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
//
|
||||
// Default frequency plan for EU 868MHz ISM band
|
||||
// data rates
|
||||
// this is a little confusing: the integer values of these constants are the
|
||||
// DataRates from the LoRaWAN Regional Parmaeter spec. The names are just
|
||||
// convenient indications, so we can use them in the rare case that we need to
|
||||
// choose a DataRate by SF and configuration, not by DR code.
|
||||
|
||||
enum _dr_eu868_t {
|
||||
EU868_DR_SF12 = 0,
|
||||
EU868_DR_SF11,
|
||||
EU868_DR_SF10,
|
||||
EU868_DR_SF9,
|
||||
EU868_DR_SF8,
|
||||
EU868_DR_SF7,
|
||||
EU868_DR_SF7B,
|
||||
EU868_DR_FSK,
|
||||
EU868_DR_NONE
|
||||
};
|
||||
|
||||
// Bands:
|
||||
// g1 : 1% 14dBm
|
||||
// g2 : 0.1% 14dBm
|
||||
// g3 : 10% 27dBm
|
||||
// freq band datarates
|
||||
enum {
|
||||
EU868_F1 = 868100000, // g1 SF7-12
|
||||
EU868_F2 = 868300000, // g1 SF7-12 FSK SF7/250
|
||||
EU868_F3 = 868500000, // g1 SF7-12
|
||||
EU868_F4 = 868850000, // g2 SF7-12
|
||||
EU868_F5 = 869050000, // g2 SF7-12
|
||||
EU868_F6 = 869525000, // g3 SF7-12
|
||||
EU868_J4 = 864100000, // g2 SF7-12 used during join
|
||||
EU868_J5 = 864300000, // g2 SF7-12 ditto
|
||||
EU868_J6 = 864500000, // g2 SF7-12 ditto
|
||||
};
|
||||
enum {
|
||||
EU868_FREQ_MIN = 863000000,
|
||||
EU868_FREQ_MAX = 870000000
|
||||
};
|
||||
enum {
|
||||
EU868_TX_EIRP_MAX_DBM = 16 // 16 dBm EIRP. So subtract 3 dBm for a 3 dBi antenna.
|
||||
};
|
||||
|
||||
enum { EU868_LMIC_REGION_EIRP = 1 }; // region uses EIRP
|
||||
|
||||
enum { DR_PAGE_EU868 = 0x10 * (LMIC_REGION_eu868 - 1) };
|
||||
|
||||
#endif /* _lorabase_eu868_h_ */
|
78
src/lmic/lorabase_in866.h
Executable file
78
src/lmic/lorabase_in866.h
Executable file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2017 MCCI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lorabase_in866_h_
|
||||
#define _lorabase_in866_h_
|
||||
|
||||
#ifndef _LMIC_CONFIG_PRECONDITIONS_H_
|
||||
# include "lmic_config_preconditions.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| Basic definitions for IN866 (always in scope)
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
enum _dr_in866_t {
|
||||
IN866_DR_SF12 = 0, // DR0
|
||||
IN866_DR_SF11, // DR1
|
||||
IN866_DR_SF10, // DR2
|
||||
IN866_DR_SF9, // DR3
|
||||
IN866_DR_SF8, // DR4
|
||||
IN866_DR_SF7, // DR5
|
||||
IN866_DR_RFU, // -
|
||||
IN866_DR_FSK, // DR7
|
||||
IN866_DR_NONE
|
||||
};
|
||||
|
||||
// There is no dwell-time or duty-cycle limitation for IN
|
||||
//
|
||||
// max power: 30dBM
|
||||
//
|
||||
// freq datarates
|
||||
enum {
|
||||
IN866_F1 = 865062500, // SF7-12 (DR0-5)
|
||||
IN866_F2 = 865402500, // SF7-12 (DR0-5)
|
||||
IN866_F3 = 865985000, // SF7-12 (DR0-5)
|
||||
IN866_FB = 866550000, // beacon/ping
|
||||
};
|
||||
enum {
|
||||
IN866_FREQ_MIN = 865000000,
|
||||
IN866_FREQ_MAX = 867000000
|
||||
};
|
||||
enum {
|
||||
IN866_TX_EIRP_MAX_DBM = 30 // 30 dBm
|
||||
};
|
||||
enum { DR_PAGE_IN866 = 0x10 * (LMIC_REGION_in866 - 1) };
|
||||
|
||||
enum { IN866_LMIC_REGION_EIRP = 1 }; // region uses EIRP
|
||||
|
||||
#endif /* _lorabase_in866_h_ */
|
84
src/lmic/lorabase_us915.h
Executable file
84
src/lmic/lorabase_us915.h
Executable file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2017 MCCI Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _lorabase_us915_h_
|
||||
#define _lorabase_us915_h_
|
||||
|
||||
#ifndef _LMIC_CONFIG_PRECONDITIONS_H_
|
||||
# include "lmic_config_preconditions.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************\
|
||||
|
|
||||
| Basic definitions for US915 (always in scope)
|
||||
|
|
||||
\****************************************************************************/
|
||||
|
||||
// Frequency plan for US 915MHz ISM band
|
||||
// data rates
|
||||
enum _dr_us915_t {
|
||||
US915_DR_SF10 = 0,
|
||||
US915_DR_SF9,
|
||||
US915_DR_SF8,
|
||||
US915_DR_SF7,
|
||||
US915_DR_SF8C,
|
||||
US915_DR_NONE,
|
||||
// Devices "behind a router" (and upper half of DR list):
|
||||
US915_DR_SF12CR = 8,
|
||||
US915_DR_SF11CR,
|
||||
US915_DR_SF10CR,
|
||||
US915_DR_SF9CR,
|
||||
US915_DR_SF8CR,
|
||||
US915_DR_SF7CR
|
||||
};
|
||||
|
||||
// Default frequency plan for US 915MHz
|
||||
enum {
|
||||
US915_125kHz_UPFBASE = 902300000,
|
||||
US915_125kHz_UPFSTEP = 200000,
|
||||
US915_500kHz_UPFBASE = 903000000,
|
||||
US915_500kHz_UPFSTEP = 1600000,
|
||||
US915_500kHz_DNFBASE = 923300000,
|
||||
US915_500kHz_DNFSTEP = 600000
|
||||
};
|
||||
enum {
|
||||
US915_FREQ_MIN = 902000000,
|
||||
US915_FREQ_MAX = 928000000
|
||||
};
|
||||
enum {
|
||||
US915_TX_MAX_DBM = 30 // 30 dBm (but not EIRP): assumes we're
|
||||
// on an 64-channel bandplan. See code
|
||||
// that computes tx power.
|
||||
};
|
||||
enum { DR_PAGE_US915 = 0x10 * (LMIC_REGION_us915 - 1) };
|
||||
|
||||
enum { US915_LMIC_REGION_EIRP = 0 }; // region doesn't use EIRP, uses tx power
|
||||
|
||||
#endif /* _lorabase_us915_h_ */
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2016-2017 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -25,9 +26,11 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define LMIC_DR_LEGACY 0
|
||||
|
||||
#include "lmic.h"
|
||||
#include "../hal/hal_esp32.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
extern const struct lmic_pinmap lmic_pins;
|
||||
|
||||
// RUNTIME STATE
|
||||
static struct {
|
||||
@ -35,18 +38,27 @@ static struct {
|
||||
osjob_t* runnablejobs;
|
||||
} OS;
|
||||
|
||||
void os_init () {
|
||||
int os_init_ex (const void *pintable) {
|
||||
memset(&OS, 0x00, sizeof(OS));
|
||||
hal_init();
|
||||
radio_init();
|
||||
hal_init_ex(pintable);
|
||||
if (! radio_init())
|
||||
return 0;
|
||||
LMIC_init();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void os_init() {
|
||||
if (os_init_ex((const void *)&lmic_pins))
|
||||
return;
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
ostime_t os_getTime () {
|
||||
return hal_ticks();
|
||||
}
|
||||
|
||||
static u1_t unlinkjob (osjob_t** pnext, osjob_t* job) {
|
||||
// unlink job from queue, return if removed
|
||||
static int unlinkjob (osjob_t** pnext, osjob_t* job) {
|
||||
for( ; *pnext; pnext = &((*pnext)->next)) {
|
||||
if(*pnext == job) { // unlink
|
||||
*pnext = job->next;
|
||||
@ -59,14 +71,9 @@ static u1_t unlinkjob (osjob_t** pnext, osjob_t* job) {
|
||||
// clear scheduled job
|
||||
void os_clearCallback (osjob_t* job) {
|
||||
hal_disableIRQs();
|
||||
u1_t res = unlinkjob(&OS.scheduledjobs, job);
|
||||
if (res)
|
||||
unlinkjob(&OS.runnablejobs, job);
|
||||
// ttn-esp32 change: suppress error 'value computed is not used'
|
||||
int __attribute__((unused)) res = unlinkjob(&OS.scheduledjobs, job) || unlinkjob(&OS.runnablejobs, job);
|
||||
hal_enableIRQs();
|
||||
#if LMIC_DEBUG_LEVEL > 1
|
||||
if (res)
|
||||
lmic_printf("%lu: Cleared job %p\n", os_getTime(), job);
|
||||
#endif
|
||||
}
|
||||
|
||||
// schedule immediately runnable job
|
||||
@ -74,7 +81,7 @@ void os_setCallback (osjob_t* job, osjobcb_t cb) {
|
||||
osjob_t** pnext;
|
||||
hal_disableIRQs();
|
||||
// remove if job was already queued
|
||||
os_clearCallback(job);
|
||||
unlinkjob(&OS.runnablejobs, job);
|
||||
// fill-in job
|
||||
job->func = cb;
|
||||
job->next = NULL;
|
||||
@ -82,9 +89,6 @@ void os_setCallback (osjob_t* job, osjobcb_t cb) {
|
||||
for(pnext=&OS.runnablejobs; *pnext; pnext=&((*pnext)->next));
|
||||
*pnext = job;
|
||||
hal_enableIRQs();
|
||||
#if LMIC_DEBUG_LEVEL > 1
|
||||
lmic_printf("%lu: Scheduled job %p, cb %p ASAP\n", os_getTime(), job, cb);
|
||||
#endif
|
||||
}
|
||||
|
||||
// schedule timed job
|
||||
@ -92,7 +96,7 @@ void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) {
|
||||
osjob_t** pnext;
|
||||
hal_disableIRQs();
|
||||
// remove if job was already queued
|
||||
os_clearCallback(job);
|
||||
unlinkjob(&OS.scheduledjobs, job);
|
||||
// fill-in job
|
||||
job->deadline = time;
|
||||
job->func = cb;
|
||||
@ -107,9 +111,6 @@ void os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb) {
|
||||
}
|
||||
*pnext = job;
|
||||
hal_enableIRQs();
|
||||
#if LMIC_DEBUG_LEVEL > 1
|
||||
lmic_printf("%lu: Scheduled job %p, cb %p at %lu\n", os_getTime(), job, cb, time);
|
||||
#endif
|
||||
}
|
||||
|
||||
// execute jobs from timer and from run queue
|
||||
@ -120,12 +121,8 @@ void os_runloop () {
|
||||
}
|
||||
|
||||
void os_runloop_once() {
|
||||
#if LMIC_DEBUG_LEVEL > 1
|
||||
bool has_deadline = false;
|
||||
#endif
|
||||
|
||||
osjob_t* j = NULL;
|
||||
hal_enterCriticalSection();
|
||||
hal_disableIRQs();
|
||||
// check for runnable jobs
|
||||
if(OS.runnablejobs) {
|
||||
j = OS.runnablejobs;
|
||||
@ -133,18 +130,11 @@ void os_runloop_once() {
|
||||
} else if(OS.scheduledjobs && hal_checkTimer(OS.scheduledjobs->deadline)) { // check for expired timed jobs
|
||||
j = OS.scheduledjobs;
|
||||
OS.scheduledjobs = j->next;
|
||||
#if LMIC_DEBUG_LEVEL > 1
|
||||
has_deadline = true;
|
||||
#endif
|
||||
}
|
||||
if(j) { // run job callback
|
||||
#if LMIC_DEBUG_LEVEL > 1
|
||||
lmic_printf("%lu: Running job %p, cb %p, deadline %lu\n", os_getTime(), j, j->func, has_deadline ? j->deadline : 0);
|
||||
#endif
|
||||
j->func(j);
|
||||
hal_leaveCriticalSection();
|
||||
} else { // nothing pending
|
||||
hal_leaveCriticalSection();
|
||||
hal_sleep(); // wake by irq (timer already restarted)
|
||||
}
|
||||
hal_enableIRQs();
|
||||
if(j) { // run job callback
|
||||
j->func(j);
|
||||
}
|
||||
}
|
||||
|
@ -35,10 +35,9 @@
|
||||
|
||||
#include "config.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
//================================================================================
|
||||
@ -49,8 +48,8 @@ typedef uint8_t u1_t;
|
||||
typedef int8_t s1_t;
|
||||
typedef uint16_t u2_t;
|
||||
typedef int16_t s2_t;
|
||||
typedef unsigned long u4_t;
|
||||
typedef long s4_t;
|
||||
typedef uint32_t u4_t;
|
||||
typedef int32_t s4_t;
|
||||
typedef unsigned int uint;
|
||||
typedef const char* str_t;
|
||||
|
||||
@ -74,6 +73,8 @@ typedef struct rxsched_t rxsched_t;
|
||||
typedef struct bcninfo_t bcninfo_t;
|
||||
typedef const u1_t* xref2cu1_t;
|
||||
typedef u1_t* xref2u1_t;
|
||||
typedef s4_t ostime_t;
|
||||
|
||||
#define TYPEDEF_xref2rps_t typedef rps_t* xref2rps_t
|
||||
#define TYPEDEF_xref2rxsched_t typedef rxsched_t* xref2rxsched_t
|
||||
#define TYPEDEF_xref2chnldef_t typedef chnldef_t* xref2chnldef_t
|
||||
@ -85,9 +86,6 @@ typedef u1_t* xref2u1_t;
|
||||
#define ON_LMIC_EVENT(ev) onEvent(ev)
|
||||
#define DECL_ON_LMIC_EVENT void onEvent(ev_t e)
|
||||
|
||||
typedef s4_t ostime_t;
|
||||
|
||||
|
||||
extern u4_t AESAUX[];
|
||||
extern u4_t AESKEY[];
|
||||
#define AESkey ((u1_t*)AESKEY)
|
||||
@ -100,11 +98,24 @@ u1_t radio_rand1 (void);
|
||||
#define DEFINE_LMIC struct lmic_t LMIC
|
||||
#define DECLARE_LMIC extern struct lmic_t LMIC
|
||||
|
||||
void radio_init (void);
|
||||
void radio_irq_handler (u1_t dio, ostime_t t);
|
||||
typedef struct oslmic_radio_rssi_s oslmic_radio_rssi_t;
|
||||
|
||||
struct oslmic_radio_rssi_s {
|
||||
s2_t min_rssi;
|
||||
s2_t max_rssi;
|
||||
s2_t mean_rssi;
|
||||
u2_t n_rssi;
|
||||
};
|
||||
|
||||
int radio_init (void);
|
||||
// ttn-esp32 extension: time parameter for radio_irq_handler
|
||||
void radio_irq_handler (u1_t dio, ostime_t now);
|
||||
void os_init (void);
|
||||
int os_init_ex (const void *pPinMap);
|
||||
void os_runloop (void);
|
||||
void os_runloop_once();
|
||||
void os_runloop_once (void);
|
||||
u1_t radio_rssi (void);
|
||||
void radio_monitor_rssi(ostime_t n, oslmic_radio_rssi_t *pRssi);
|
||||
|
||||
//================================================================================
|
||||
|
||||
@ -209,19 +220,82 @@ void os_wlsbf2 (xref2u1_t buf, u2_t value);
|
||||
#define os_getRndU2() ((u2_t)((os_getRndU1()<<8)|os_getRndU1()))
|
||||
#endif
|
||||
#ifndef os_crc16
|
||||
u2_t os_crc16 (xref2u1_t d, uint len);
|
||||
u2_t os_crc16 (xref2cu1_t d, uint len);
|
||||
#endif
|
||||
|
||||
#endif // !HAS_os_calls
|
||||
|
||||
#define lmic_printf printf
|
||||
// ======================================================================
|
||||
// Table support
|
||||
// These macros for defining a table of constants and retrieving values
|
||||
// from it makes it easier for other platforms (like AVR) to optimize
|
||||
// table accesses.
|
||||
// Use CONST_TABLE() whenever declaring or defining a table, and
|
||||
// TABLE_GET_xx whenever accessing its values. The actual name of the
|
||||
// declared variable will be modified to prevent accidental direct
|
||||
// access. The accessor macros forward to an inline function to allow
|
||||
// proper type checking of the array element type.
|
||||
|
||||
// Helper to add a prefix to the table name
|
||||
#define RESOLVE_TABLE(table) constant_table_ ## table
|
||||
|
||||
// get number of entries in table
|
||||
#define LENOF_TABLE(table) (sizeof(RESOLVE_TABLE(table)) / sizeof(RESOLVE_TABLE(table)[0]))
|
||||
|
||||
// Accessors for table elements
|
||||
#define TABLE_GET_U1(table, index) table_get_u1(RESOLVE_TABLE(table), index)
|
||||
#define TABLE_GET_S1(table, index) table_get_s1(RESOLVE_TABLE(table), index)
|
||||
#define TABLE_GET_U2(table, index) table_get_u2(RESOLVE_TABLE(table), index)
|
||||
#define TABLE_GET_S2(table, index) table_get_s2(RESOLVE_TABLE(table), index)
|
||||
#define TABLE_GET_U4(table, index) table_get_u4(RESOLVE_TABLE(table), index)
|
||||
#define TABLE_GET_S4(table, index) table_get_s4(RESOLVE_TABLE(table), index)
|
||||
#define TABLE_GET_OSTIME(table, index) table_get_ostime(RESOLVE_TABLE(table), index)
|
||||
#define TABLE_GET_U1_TWODIM(table, index1, index2) table_get_u1(RESOLVE_TABLE(table)[index1], index2)
|
||||
|
||||
#if defined(__AVR__)
|
||||
#include <avr/pgmspace.h>
|
||||
// Macro to define the getter functions. This loads data from
|
||||
// progmem using pgm_read_xx, or accesses memory directly when the
|
||||
// index is a constant so gcc can optimize it away;
|
||||
#define TABLE_GETTER(postfix, type, pgm_type) \
|
||||
inline type table_get ## postfix(const type *table, size_t index) { \
|
||||
if (__builtin_constant_p(table[index])) \
|
||||
return table[index]; \
|
||||
return pgm_read_ ## pgm_type(&table[index]); \
|
||||
}
|
||||
|
||||
TABLE_GETTER(_u1, u1_t, byte);
|
||||
TABLE_GETTER(_s1, s1_t, byte);
|
||||
TABLE_GETTER(_u2, u2_t, word);
|
||||
TABLE_GETTER(_s2, s2_t, word);
|
||||
TABLE_GETTER(_u4, u4_t, dword);
|
||||
TABLE_GETTER(_s4, s4_t, dword);
|
||||
|
||||
// This assumes ostime_t is 4 bytes, so error out if it is not
|
||||
typedef int check_sizeof_ostime_t[(sizeof(ostime_t) == 4) ? 0 : -1];
|
||||
TABLE_GETTER(_ostime, ostime_t, dword);
|
||||
|
||||
// For AVR, store constants in PROGMEM, saving on RAM usage
|
||||
#define CONST_TABLE(type, name) const type PROGMEM RESOLVE_TABLE(name)
|
||||
#else
|
||||
inline u1_t table_get_u1(const u1_t *table, size_t index) { return table[index]; }
|
||||
inline s1_t table_get_s1(const s1_t *table, size_t index) { return table[index]; }
|
||||
inline u2_t table_get_u2(const u2_t *table, size_t index) { return table[index]; }
|
||||
inline s2_t table_get_s2(const s2_t *table, size_t index) { return table[index]; }
|
||||
inline u4_t table_get_u4(const u4_t *table, size_t index) { return table[index]; }
|
||||
inline s4_t table_get_s4(const s4_t *table, size_t index) { return table[index]; }
|
||||
inline ostime_t table_get_ostime(const ostime_t *table, size_t index) { return table[index]; }
|
||||
|
||||
// Declare a table
|
||||
#define CONST_TABLE(type, name) const type RESOLVE_TABLE(name)
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
// AES support
|
||||
// AES support
|
||||
// !!Keep in sync with lorabase.hpp!!
|
||||
|
||||
#ifndef AES_ENC // if AES_ENC is defined as macro all other values must be too
|
||||
#define AES_ENC 0x00
|
||||
#define AES_ENC 0x00
|
||||
#define AES_DEC 0x01
|
||||
#define AES_MIC 0x02
|
||||
#define AES_CTR 0x04
|
||||
|
330
src/lmic/radio.c
330
src/lmic/radio.c
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2016 IBM Corporation.
|
||||
* Copyright (c) 2016-2018 MCCI Corporation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -25,10 +26,11 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
#define LMIC_DR_LEGACY 0
|
||||
|
||||
#include "lmic.h"
|
||||
|
||||
// ----------------------------------------
|
||||
// ----------------------------------------
|
||||
// Registers Mapping
|
||||
#define RegFifo 0x00 // common
|
||||
#define RegOpMode 0x01 // common
|
||||
@ -48,46 +50,46 @@
|
||||
#define FSKRegRssiConfig 0x0E
|
||||
#define LORARegFifoTxBaseAddr 0x0E
|
||||
#define FSKRegRssiCollision 0x0F
|
||||
#define LORARegFifoRxBaseAddr 0x0F
|
||||
#define LORARegFifoRxBaseAddr 0x0F
|
||||
#define FSKRegRssiThresh 0x10
|
||||
#define LORARegFifoRxCurrentAddr 0x10
|
||||
#define FSKRegRssiValue 0x11
|
||||
#define LORARegIrqFlagsMask 0x11
|
||||
#define LORARegIrqFlagsMask 0x11
|
||||
#define FSKRegRxBw 0x12
|
||||
#define LORARegIrqFlags 0x12
|
||||
#define LORARegIrqFlags 0x12
|
||||
#define FSKRegAfcBw 0x13
|
||||
#define LORARegRxNbBytes 0x13
|
||||
#define LORARegRxNbBytes 0x13
|
||||
#define FSKRegOokPeak 0x14
|
||||
#define LORARegRxHeaderCntValueMsb 0x14
|
||||
#define LORARegRxHeaderCntValueMsb 0x14
|
||||
#define FSKRegOokFix 0x15
|
||||
#define LORARegRxHeaderCntValueLsb 0x15
|
||||
#define LORARegRxHeaderCntValueLsb 0x15
|
||||
#define FSKRegOokAvg 0x16
|
||||
#define LORARegRxPacketCntValueMsb 0x16
|
||||
#define LORARegRxpacketCntValueLsb 0x17
|
||||
#define LORARegModemStat 0x18
|
||||
#define LORARegPktSnrValue 0x19
|
||||
#define LORARegRxPacketCntValueMsb 0x16
|
||||
#define LORARegRxpacketCntValueLsb 0x17
|
||||
#define LORARegModemStat 0x18
|
||||
#define LORARegPktSnrValue 0x19
|
||||
#define FSKRegAfcFei 0x1A
|
||||
#define LORARegPktRssiValue 0x1A
|
||||
#define LORARegPktRssiValue 0x1A
|
||||
#define FSKRegAfcMsb 0x1B
|
||||
#define LORARegRssiValue 0x1B
|
||||
#define LORARegRssiValue 0x1B
|
||||
#define FSKRegAfcLsb 0x1C
|
||||
#define LORARegHopChannel 0x1C
|
||||
#define LORARegHopChannel 0x1C
|
||||
#define FSKRegFeiMsb 0x1D
|
||||
#define LORARegModemConfig1 0x1D
|
||||
#define LORARegModemConfig1 0x1D
|
||||
#define FSKRegFeiLsb 0x1E
|
||||
#define LORARegModemConfig2 0x1E
|
||||
#define LORARegModemConfig2 0x1E
|
||||
#define FSKRegPreambleDetect 0x1F
|
||||
#define LORARegSymbTimeoutLsb 0x1F
|
||||
#define LORARegSymbTimeoutLsb 0x1F
|
||||
#define FSKRegRxTimeout1 0x20
|
||||
#define LORARegPreambleMsb 0x20
|
||||
#define LORARegPreambleMsb 0x20
|
||||
#define FSKRegRxTimeout2 0x21
|
||||
#define LORARegPreambleLsb 0x21
|
||||
#define LORARegPreambleLsb 0x21
|
||||
#define FSKRegRxTimeout3 0x22
|
||||
#define LORARegPayloadLength 0x22
|
||||
#define LORARegPayloadLength 0x22
|
||||
#define FSKRegRxDelay 0x23
|
||||
#define LORARegPayloadMaxLength 0x23
|
||||
#define LORARegPayloadMaxLength 0x23
|
||||
#define FSKRegOsc 0x24
|
||||
#define LORARegHopPeriod 0x24
|
||||
#define LORARegHopPeriod 0x24
|
||||
#define FSKRegPreambleMsb 0x25
|
||||
#define LORARegFifoRxByteAddr 0x25
|
||||
#define LORARegModemConfig3 0x26
|
||||
@ -133,8 +135,8 @@
|
||||
// #define RegAgcThresh2 0x45 // common
|
||||
// #define RegAgcThresh3 0x46 // common
|
||||
// #define RegPllHop 0x4B // common
|
||||
#define RegPaDac 0x4D // common
|
||||
// #define RegTcxo 0x58 // common
|
||||
#define RegPaDac 0x5A // common
|
||||
// #define RegPll 0x5C // common
|
||||
// #define RegPllLowPn 0x5E // common
|
||||
// #define RegFormerTemp 0x6C // common
|
||||
@ -175,12 +177,12 @@
|
||||
#define SX1276_MC1_CR_4_7 0x06
|
||||
#define SX1276_MC1_CR_4_8 0x08
|
||||
|
||||
#define SX1276_MC1_IMPLICIT_HEADER_MODE_ON 0x01
|
||||
|
||||
// sx1276 RegModemConfig2
|
||||
#define SX1276_MC1_IMPLICIT_HEADER_MODE_ON 0x01
|
||||
|
||||
// sx1276 RegModemConfig2
|
||||
#define SX1276_MC2_RX_PAYLOAD_CRCON 0x04
|
||||
|
||||
// sx1276 RegModemConfig3
|
||||
// sx1276 RegModemConfig3
|
||||
#define SX1276_MC3_LOW_DATA_RATE_OPTIMIZE 0x08
|
||||
#define SX1276_MC3_AGCAUTO 0x04
|
||||
|
||||
@ -194,9 +196,19 @@
|
||||
#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x74
|
||||
#endif
|
||||
|
||||
//-----------------------------------------
|
||||
// Parameters for RSSI monitoring
|
||||
#define SX127X_FREQ_LF_MAX 525000000 // per datasheet 6.3
|
||||
|
||||
// per datasheet 5.5.3:
|
||||
#define SX127X_RSSI_ADJUST_LF -164 // add to rssi value to get dB (LF)
|
||||
#define SX127X_RSSI_ADJUST_HF -157 // add to rssi value to get dB (HF)
|
||||
|
||||
// per datasheet 2.5.2 (but note that we ought to ask Semtech to confirm, because
|
||||
// datasheet is unclear).
|
||||
#define SX127X_RX_POWER_UP us2osticks(500) // delay this long to let the receiver power up.
|
||||
|
||||
// ----------------------------------------
|
||||
// ----------------------------------------
|
||||
// Constants for radio registers
|
||||
#define OPMODE_LORA 0x80
|
||||
#define OPMODE_MASK 0x07
|
||||
@ -206,8 +218,8 @@
|
||||
#define OPMODE_TX 0x03
|
||||
#define OPMODE_FSRX 0x04
|
||||
#define OPMODE_RX 0x05
|
||||
#define OPMODE_RX_SINGLE 0x06
|
||||
#define OPMODE_CAD 0x07
|
||||
#define OPMODE_RX_SINGLE 0x06
|
||||
#define OPMODE_CAD 0x07
|
||||
|
||||
// ----------------------------------------
|
||||
// Bits masking the corresponding IRQs from the radio
|
||||
@ -278,6 +290,7 @@ static u1_t randbuf[16];
|
||||
|
||||
|
||||
static void writeReg (u1_t addr, u1_t data ) {
|
||||
// ttn-esp32 change: higher level SPI interface
|
||||
hal_spi_write(addr | 0x80, &data, 1);
|
||||
/*
|
||||
hal_pin_nss(0);
|
||||
@ -288,6 +301,7 @@ static void writeReg (u1_t addr, u1_t data ) {
|
||||
}
|
||||
|
||||
static u1_t readReg (u1_t addr) {
|
||||
// ttn-esp32 change: higher level SPI interface
|
||||
u1_t buf[1];
|
||||
hal_spi_read(addr & 0x7f, buf, 1);
|
||||
return buf[0];
|
||||
@ -301,6 +315,7 @@ static u1_t readReg (u1_t addr) {
|
||||
}
|
||||
|
||||
static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) {
|
||||
// ttn-esp32 change: higher level SPI interface
|
||||
hal_spi_write(addr | 0x80, buf, len);
|
||||
/*
|
||||
hal_pin_nss(0);
|
||||
@ -313,6 +328,7 @@ static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) {
|
||||
}
|
||||
|
||||
static void readBuf (u1_t addr, xref2u1_t buf, u1_t len) {
|
||||
// ttn-esp32 change: higher level SPI interface
|
||||
hal_spi_read(addr & 0x7f, buf, len);
|
||||
/*
|
||||
hal_pin_nss(0);
|
||||
@ -379,7 +395,7 @@ static void configLoraModem () {
|
||||
mc2 |= SX1276_MC2_RX_PAYLOAD_CRCON;
|
||||
}
|
||||
writeReg(LORARegModemConfig2, mc2);
|
||||
|
||||
|
||||
mc3 = SX1276_MC3_AGCAUTO;
|
||||
if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) {
|
||||
mc3 |= SX1276_MC3_LOW_DATA_RATE_OPTIMIZE;
|
||||
@ -394,24 +410,31 @@ static void configLoraModem () {
|
||||
case CR_4_7: mc1 |= SX1272_MC1_CR_4_7; break;
|
||||
case CR_4_8: mc1 |= SX1272_MC1_CR_4_8; break;
|
||||
}
|
||||
|
||||
|
||||
if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) {
|
||||
mc1 |= SX1272_MC1_LOW_DATA_RATE_OPTIMIZE;
|
||||
}
|
||||
|
||||
|
||||
if (getNocrc(LMIC.rps) == 0) {
|
||||
mc1 |= SX1272_MC1_RX_PAYLOAD_CRCON;
|
||||
}
|
||||
|
||||
|
||||
if (getIh(LMIC.rps)) {
|
||||
mc1 |= SX1272_MC1_IMPLICIT_HEADER_MODE_ON;
|
||||
writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length
|
||||
}
|
||||
// set ModemConfig1
|
||||
writeReg(LORARegModemConfig1, mc1);
|
||||
|
||||
|
||||
// set ModemConfig2 (sf, AgcAutoOn=1 SymbTimeoutHi=00)
|
||||
writeReg(LORARegModemConfig2, (SX1272_MC2_SF7 + ((sf-1)<<4)) | 0x04);
|
||||
|
||||
#if CFG_TxContinuousMode
|
||||
// Only for testing
|
||||
// set ModemConfig2 (sf, TxContinuousMode=1, AgcAutoOn=1 SymbTimeoutHi=00)
|
||||
writeReg(LORARegModemConfig2, (SX1272_MC2_SF7 + ((sf-1)<<4)) | 0x06);
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
|
||||
#endif /* CFG_sx1272_radio */
|
||||
@ -429,15 +452,19 @@ static void configChannel () {
|
||||
|
||||
static void configPower () {
|
||||
#ifdef CFG_sx1276_radio
|
||||
// no boost used for now
|
||||
// PA_BOOST output is assumed but not 20 dBm.
|
||||
s1_t pw = (s1_t)LMIC.txpow;
|
||||
if(pw >= 17) {
|
||||
pw = 15;
|
||||
if(pw > 17) {
|
||||
pw = 17;
|
||||
} else if(pw < 2) {
|
||||
pw = 2;
|
||||
}
|
||||
// check board type for BOOST pin
|
||||
writeReg(RegPaConfig, (u1_t)(0x80|(pw&0xf)));
|
||||
// 0x80 forces use of PA_BOOST; but we don't
|
||||
// turn on 20 dBm mode. So powers are:
|
||||
// 0000 => 2dBm, 0001 => 3dBm, ... 1111 => 17dBm
|
||||
// But we also enforce that the high-power mode
|
||||
// is off by writing RegPaDac.
|
||||
writeReg(RegPaConfig, (u1_t)(0x80|(pw - 2)));
|
||||
writeReg(RegPaDac, readReg(RegPaDac)|0x4);
|
||||
|
||||
#elif CFG_sx1272_radio
|
||||
@ -483,7 +510,7 @@ static void txfsk () {
|
||||
// set the IRQ mapping DIO0=PacketSent DIO1=NOP DIO2=NOP
|
||||
writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TXNOP);
|
||||
|
||||
// initialize the payload size and address pointers
|
||||
// initialize the payload size and address pointers
|
||||
writeReg(FSKRegPayloadLength, LMIC.dataLen+1); // (insert length byte into payload))
|
||||
|
||||
// download length byte and buffer to the radio FIFO
|
||||
@ -492,7 +519,7 @@ static void txfsk () {
|
||||
|
||||
// enable antenna switch for TX
|
||||
hal_pin_rxtx(1);
|
||||
|
||||
|
||||
// now we actually start the transmission
|
||||
opmode(OPMODE_TX);
|
||||
}
|
||||
@ -501,16 +528,7 @@ static void txlora () {
|
||||
// select LoRa modem (from sleep mode)
|
||||
//writeReg(RegOpMode, OPMODE_LORA);
|
||||
opmodeLora();
|
||||
// can take a moment to change; so try ten times
|
||||
u1_t reg;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
reg = readReg(RegOpMode);
|
||||
if ((reg & OPMODE_LORA) != 0)
|
||||
break;
|
||||
ets_delay_us(100);
|
||||
}
|
||||
ASSERT((reg & OPMODE_LORA) != 0);
|
||||
ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0);
|
||||
|
||||
// enter standby mode (required for FIFO loading))
|
||||
opmode(OPMODE_STANDBY);
|
||||
@ -523,7 +541,7 @@ static void txlora () {
|
||||
configPower();
|
||||
// set sync word
|
||||
writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE);
|
||||
|
||||
|
||||
// set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP
|
||||
writeReg(RegDioMapping1, MAP_DIO0_LORA_TXDONE|MAP_DIO1_LORA_NOP|MAP_DIO2_LORA_NOP);
|
||||
// clear all radio IRQ flags
|
||||
@ -531,17 +549,17 @@ static void txlora () {
|
||||
// mask all IRQs but TxDone
|
||||
writeReg(LORARegIrqFlagsMask, ~IRQ_LORA_TXDONE_MASK);
|
||||
|
||||
// initialize the payload size and address pointers
|
||||
// initialize the payload size and address pointers
|
||||
writeReg(LORARegFifoTxBaseAddr, 0x00);
|
||||
writeReg(LORARegFifoAddrPtr, 0x00);
|
||||
writeReg(LORARegPayloadLength, LMIC.dataLen);
|
||||
|
||||
|
||||
// download buffer to the radio FIFO
|
||||
writeBuf(RegFifo, LMIC.frame, LMIC.dataLen);
|
||||
|
||||
// enable antenna switch for TX
|
||||
hal_pin_rxtx(1);
|
||||
|
||||
|
||||
// now we actually start the transmission
|
||||
opmode(OPMODE_TX);
|
||||
|
||||
@ -549,8 +567,9 @@ static void txlora () {
|
||||
u1_t sf = getSf(LMIC.rps) + 6; // 1 == SF7
|
||||
u1_t bw = getBw(LMIC.rps);
|
||||
u1_t cr = getCr(LMIC.rps);
|
||||
lmic_printf("%lu: TXMODE, freq=%lu, len=%d, SF=%d, BW=%d, CR=4/%d, IH=%d\n",
|
||||
os_getTime(), LMIC.freq, LMIC.dataLen, sf,
|
||||
// ttn-esp32 change: fix printf for for ostime_t and freq
|
||||
LMIC_DEBUG_PRINTF("%u: TXMODE, freq=%u, len=%d, SF=%d, BW=%d, CR=4/%d, IH=%d\n",
|
||||
(unsigned)os_getTime(), LMIC.freq, LMIC.dataLen, sf,
|
||||
bw == BW125 ? 125 : (bw == BW250 ? 250 : 500),
|
||||
cr == CR_4_5 ? 5 : (cr == CR_4_6 ? 6 : (cr == CR_4_7 ? 7 : 8)),
|
||||
getIh(LMIC.rps)
|
||||
@ -560,7 +579,33 @@ static void txlora () {
|
||||
|
||||
// start transmitter (buf=LMIC.frame, len=LMIC.dataLen)
|
||||
static void starttx () {
|
||||
ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP );
|
||||
u1_t const rOpMode = readReg(RegOpMode);
|
||||
|
||||
// originally, this code ASSERT()ed, but asserts are both bad and
|
||||
// blunt instruments. If we see that we're not in sleep mode,
|
||||
// force sleep (because we might have to switch modes)
|
||||
if ((rOpMode & OPMODE_MASK) != OPMODE_SLEEP) {
|
||||
#if LMIC_DEBUG_LEVEL > 0
|
||||
LMIC_DEBUG_PRINTF("?%s: OPMODE != OPMODE_SLEEP: %#02x\n", __func__, rOpMode);
|
||||
#endif
|
||||
opmode(OPMODE_SLEEP);
|
||||
hal_waitUntil(os_getTime() + ms2osticks(1));
|
||||
}
|
||||
|
||||
if (LMIC.lbt_ticks > 0) {
|
||||
oslmic_radio_rssi_t rssi;
|
||||
radio_monitor_rssi(LMIC.lbt_ticks, &rssi);
|
||||
#if LMIC_X_DEBUG_LEVEL > 0
|
||||
LMIC_X_DEBUG_PRINTF("LBT rssi max:min=%d:%d %d times in %d\n", rssi.max_rssi, rssi.min_rssi, rssi.n_rssi, LMIC.lbt_ticks);
|
||||
#endif
|
||||
|
||||
if (rssi.max_rssi >= LMIC.lbt_dbmax) {
|
||||
// complete the request by scheduling the job
|
||||
os_setCallback(&LMIC.osjob, LMIC.osjob.func);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(getSf(LMIC.rps) == FSK) { // FSK modem
|
||||
txfsk();
|
||||
} else { // LoRa modem
|
||||
@ -572,7 +617,7 @@ static void starttx () {
|
||||
|
||||
enum { RXMODE_SINGLE, RXMODE_SCAN, RXMODE_RSSI };
|
||||
|
||||
static const u1_t rxlorairqmask[] = {
|
||||
static CONST_TABLE(u1_t, rxlorairqmask)[] = {
|
||||
[RXMODE_SINGLE] = IRQ_LORA_RXDONE_MASK|IRQ_LORA_RXTOUT_MASK,
|
||||
[RXMODE_SCAN] = IRQ_LORA_RXDONE_MASK,
|
||||
[RXMODE_RSSI] = 0x00,
|
||||
@ -596,7 +641,7 @@ static void rxlora (u1_t rxmode) {
|
||||
configChannel();
|
||||
}
|
||||
// set LNA gain
|
||||
writeReg(RegLna, LNA_RX_GAIN);
|
||||
writeReg(RegLna, LNA_RX_GAIN);
|
||||
// set max payload size
|
||||
writeReg(LORARegPayloadMaxLength, 64);
|
||||
#if !defined(DISABLE_INVERT_IQ_ON_RX)
|
||||
@ -613,13 +658,13 @@ static void rxlora (u1_t rxmode) {
|
||||
writeReg(LORARegSymbTimeoutLsb, LMIC.rxsyms);
|
||||
// set sync word
|
||||
writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE);
|
||||
|
||||
|
||||
// configure DIO mapping DIO0=RxDone DIO1=RxTout DIO2=NOP
|
||||
writeReg(RegDioMapping1, MAP_DIO0_LORA_RXDONE|MAP_DIO1_LORA_RXTOUT|MAP_DIO2_LORA_NOP);
|
||||
// clear all radio IRQ flags
|
||||
writeReg(LORARegIrqFlags, 0xFF);
|
||||
// enable required radio IRQs
|
||||
writeReg(LORARegIrqFlagsMask, ~rxlorairqmask[rxmode]);
|
||||
writeReg(LORARegIrqFlagsMask, ~TABLE_GET_U1(rxlorairqmask, rxmode));
|
||||
|
||||
// enable antenna switch for RX
|
||||
hal_pin_rxtx(0);
|
||||
@ -628,19 +673,25 @@ static void rxlora (u1_t rxmode) {
|
||||
if (rxmode == RXMODE_SINGLE) { // single rx
|
||||
hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
|
||||
opmode(OPMODE_RX_SINGLE);
|
||||
#if LMIC_DEBUG_LEVEL > 0
|
||||
ostime_t now = os_getTime();
|
||||
// ttn-esp32 change: fix printf for for ostime_t
|
||||
LMIC_DEBUG_PRINTF("start single rx: now-rxtime: %u\n", (unsigned)(now - LMIC.rxtime));
|
||||
#endif
|
||||
} else { // continous rx (scan or rssi)
|
||||
opmode(OPMODE_RX);
|
||||
opmode(OPMODE_RX);
|
||||
}
|
||||
|
||||
#if LMIC_DEBUG_LEVEL > 0
|
||||
if (rxmode == RXMODE_RSSI) {
|
||||
lmic_printf("RXMODE_RSSI\n");
|
||||
LMIC_DEBUG_PRINTF("RXMODE_RSSI\n");
|
||||
} else {
|
||||
u1_t sf = getSf(LMIC.rps) + 6; // 1 == SF7
|
||||
u1_t bw = getBw(LMIC.rps);
|
||||
u1_t cr = getCr(LMIC.rps);
|
||||
lmic_printf("%lu: %s, freq=%lu, SF=%d, BW=%d, CR=4/%d, IH=%d\n",
|
||||
os_getTime(),
|
||||
// ttn-esp32 change: fix printf for for ostime_t and freq
|
||||
LMIC_DEBUG_PRINTF("%u: %s, freq=%u, SF=%d, BW=%d, CR=4/%d, IH=%d\n",
|
||||
(unsigned)os_getTime(),
|
||||
rxmode == RXMODE_SINGLE ? "RXMODE_SINGLE" : (rxmode == RXMODE_SCAN ? "RXMODE_SCAN" : "UNKNOWN_RX"),
|
||||
LMIC.freq, sf,
|
||||
bw == BW125 ? 125 : (bw == BW250 ? 250 : 500),
|
||||
@ -690,13 +741,13 @@ static void rxfsk (u1_t rxmode) {
|
||||
// set frequency deviation
|
||||
writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz
|
||||
writeReg(FSKRegFdevLsb, 0x99);
|
||||
|
||||
|
||||
// configure DIO mapping DIO0=PayloadReady DIO1=NOP DIO2=TimeOut
|
||||
writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TIMEOUT);
|
||||
|
||||
// enable antenna switch for RX
|
||||
hal_pin_rxtx(0);
|
||||
|
||||
|
||||
// now instruct the radio to receive
|
||||
hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
|
||||
opmode(OPMODE_RX); // no single rx mode available in FSK
|
||||
@ -714,7 +765,7 @@ static void startrx (u1_t rxmode) {
|
||||
}
|
||||
|
||||
// get random seed from wideband noise rssi
|
||||
void radio_init () {
|
||||
int radio_init () {
|
||||
hal_disableIRQs();
|
||||
|
||||
// manually reset radio
|
||||
@ -732,9 +783,11 @@ void radio_init () {
|
||||
// some sanity checks, e.g., read version number
|
||||
u1_t v = readReg(RegVersion);
|
||||
#ifdef CFG_sx1276_radio
|
||||
ASSERT(v == 0x12 );
|
||||
if(v != 0x12 )
|
||||
return 0;
|
||||
#elif CFG_sx1272_radio
|
||||
ASSERT(v == 0x22);
|
||||
if(v != 0x22)
|
||||
return 0;
|
||||
#else
|
||||
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
|
||||
#endif
|
||||
@ -749,11 +802,11 @@ void radio_init () {
|
||||
}
|
||||
}
|
||||
randbuf[0] = 16; // set initial index
|
||||
|
||||
|
||||
#ifdef CFG_sx1276mb1_board
|
||||
// chain calibration
|
||||
writeReg(RegPaConfig, 0);
|
||||
|
||||
|
||||
// Launch Rx chain calibration for LF band
|
||||
writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START);
|
||||
while((readReg(FSKRegImageCal)&RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING){ ; }
|
||||
@ -764,7 +817,7 @@ void radio_init () {
|
||||
writeReg(RegFrfMid, (u1_t)(frf>> 8));
|
||||
writeReg(RegFrfLsb, (u1_t)(frf>> 0));
|
||||
|
||||
// Launch Rx chain calibration for HF band
|
||||
// Launch Rx chain calibration for HF band
|
||||
writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START);
|
||||
while((readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING) { ; }
|
||||
#endif /* CFG_sx1276mb1_board */
|
||||
@ -772,6 +825,7 @@ void radio_init () {
|
||||
opmode(OPMODE_SLEEP);
|
||||
|
||||
hal_enableIRQs();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// return next random byte derived from seed buffer
|
||||
@ -795,7 +849,83 @@ u1_t radio_rssi () {
|
||||
return r;
|
||||
}
|
||||
|
||||
static const u2_t LORA_RXDONE_FIXUP[] = {
|
||||
// monitor rssi for specified number of ostime_t ticks, and return statistics
|
||||
// This puts the radio into RX continuous mode, waits long enough for the
|
||||
// oscillators to start and the PLL to lock, and then measures for the specified
|
||||
// period of time. The radio is then returned to idle.
|
||||
//
|
||||
// RSSI returned is expressed in units of dB, and is offset according to the
|
||||
// current radio setting per section 5.5.5 of Semtech 1276 datasheet.
|
||||
void radio_monitor_rssi(ostime_t nTicks, oslmic_radio_rssi_t *pRssi) {
|
||||
uint8_t rssiMax, rssiMin;
|
||||
uint16_t rssiSum;
|
||||
uint16_t rssiN;
|
||||
|
||||
int rssiAdjust;
|
||||
ostime_t tBegin;
|
||||
int notDone;
|
||||
|
||||
rxlora(RXMODE_SCAN);
|
||||
|
||||
// while we're waiting for the PLLs to spin up, determine which
|
||||
// band we're in and choose the base RSSI.
|
||||
if (LMIC.freq > SX127X_FREQ_LF_MAX) {
|
||||
rssiAdjust = SX127X_RSSI_ADJUST_HF;
|
||||
} else {
|
||||
rssiAdjust = SX127X_RSSI_ADJUST_LF;
|
||||
}
|
||||
rssiAdjust += hal_getRssiCal();
|
||||
|
||||
// zero the results
|
||||
rssiMax = 255;
|
||||
rssiMin = 0;
|
||||
rssiSum = 0;
|
||||
rssiN = 0;
|
||||
|
||||
// wait for PLLs
|
||||
hal_waitUntil(os_getTime() + SX127X_RX_POWER_UP);
|
||||
|
||||
// scan for the desired time.
|
||||
tBegin = os_getTime();
|
||||
rssiMax = 0;
|
||||
|
||||
/* XXX(tanupoo)
|
||||
* In this loop, micros() in os_getTime() returns a past time sometimes.
|
||||
* At least, it happens on Dragino LoRa Mini.
|
||||
* the return value of micros() looks not to be stable in IRQ disabled.
|
||||
* Once it happens, this loop never exit infinitely.
|
||||
* In order to prevent it, it enables IRQ before calling os_getTime(),
|
||||
* disable IRQ again after that.
|
||||
*/
|
||||
do {
|
||||
ostime_t now;
|
||||
|
||||
u1_t rssiNow = readReg(LORARegRssiValue);
|
||||
|
||||
if (rssiMax < rssiNow)
|
||||
rssiMax = rssiNow;
|
||||
if (rssiNow < rssiMin)
|
||||
rssiMin = rssiNow;
|
||||
rssiSum += rssiNow;
|
||||
++rssiN;
|
||||
// TODO(tmm@mcci.com) move this to os_getTime().
|
||||
hal_enableIRQs();
|
||||
now = os_getTime();
|
||||
hal_disableIRQs();
|
||||
notDone = now - (tBegin + nTicks) < 0;
|
||||
} while (notDone);
|
||||
|
||||
// put radio back to sleep
|
||||
opmode(OPMODE_SLEEP);
|
||||
|
||||
// compute the results
|
||||
pRssi->max_rssi = (s2_t) (rssiMax + rssiAdjust);
|
||||
pRssi->min_rssi = (s2_t) (rssiMin + rssiAdjust);
|
||||
pRssi->mean_rssi = (s2_t) (rssiAdjust + ((rssiSum + (rssiN >> 1)) / rssiN));
|
||||
pRssi->n_rssi = rssiN;
|
||||
}
|
||||
|
||||
static CONST_TABLE(u2_t, LORA_RXDONE_FIXUP)[] = {
|
||||
[FSK] = us2osticks(0), // ( 0 ticks)
|
||||
[SF7] = us2osticks(0), // ( 0 ticks)
|
||||
[SF8] = us2osticks(1648), // ( 54 ticks)
|
||||
@ -807,34 +937,55 @@ static const u2_t LORA_RXDONE_FIXUP[] = {
|
||||
|
||||
// called by hal ext IRQ handler
|
||||
// (radio goes to stanby mode after tx/rx operations)
|
||||
void radio_irq_handler (u1_t dio, ostime_t t) {
|
||||
// ttn-esp32 change: additional time paramter
|
||||
void radio_irq_handler (u1_t dio, ostime_t now) {
|
||||
#if CFG_TxContinuousMode
|
||||
// clear radio IRQ flags
|
||||
writeReg(LORARegIrqFlags, 0xFF);
|
||||
u1_t p = readReg(LORARegFifoAddrPtr);
|
||||
writeReg(LORARegFifoAddrPtr, 0x00);
|
||||
u1_t s = readReg(RegOpMode);
|
||||
u1_t c = readReg(LORARegModemConfig2);
|
||||
opmode(OPMODE_TX);
|
||||
return;
|
||||
#else /* ! CFG_TxContinuousMode */
|
||||
// ttn-esp32 change: use provided time parameter
|
||||
// ostime_t now = os_getTime();
|
||||
#if LMIC_DEBUG_LEVEL > 0
|
||||
ostime_t const entry = now;
|
||||
#endif
|
||||
if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem
|
||||
u1_t flags = readReg(LORARegIrqFlags);
|
||||
#if LMIC_DEBUG_LEVEL > 1
|
||||
lmic_printf("%lu: irq: dio: 0x%x flags: 0x%x\n", t, dio, flags);
|
||||
#endif
|
||||
LMIC_X_DEBUG_PRINTF("IRQ=%02x\n", flags);
|
||||
if( flags & IRQ_LORA_TXDONE_MASK ) {
|
||||
// save exact tx time
|
||||
LMIC.txend = t - us2osticks(43); // TXDONE FIXUP
|
||||
LMIC.txend = now - us2osticks(43); // TXDONE FIXUP
|
||||
} else if( flags & IRQ_LORA_RXDONE_MASK ) {
|
||||
// save exact rx time
|
||||
if(getBw(LMIC.rps) == BW125) {
|
||||
t -= LORA_RXDONE_FIXUP[getSf(LMIC.rps)];
|
||||
now -= TABLE_GET_U2(LORA_RXDONE_FIXUP, getSf(LMIC.rps));
|
||||
}
|
||||
LMIC.rxtime = t;
|
||||
LMIC.rxtime = now;
|
||||
// read the PDU and inform the MAC that we received something
|
||||
LMIC.dataLen = (readReg(LORARegModemConfig1) & SX1272_MC1_IMPLICIT_HEADER_MODE_ON) ?
|
||||
readReg(LORARegPayloadLength) : readReg(LORARegRxNbBytes);
|
||||
// set FIFO read address pointer
|
||||
writeReg(LORARegFifoAddrPtr, readReg(LORARegFifoRxCurrentAddr));
|
||||
writeReg(LORARegFifoAddrPtr, readReg(LORARegFifoRxCurrentAddr));
|
||||
// now read the FIFO
|
||||
readBuf(RegFifo, LMIC.frame, LMIC.dataLen);
|
||||
// read rx quality parameters
|
||||
LMIC.snr = readReg(LORARegPktSnrValue); // SNR [dB] * 4
|
||||
LMIC.rssi = readReg(LORARegPktRssiValue) - 125 + 64; // RSSI [dBm] (-196...+63)
|
||||
LMIC.rssi = readReg(LORARegPktRssiValue);
|
||||
LMIC_X_DEBUG_PRINTF("RX snr=%u rssi=%d\n", LMIC.snr/4, SX127X_RSSI_ADJUST_HF + LMIC.rssi);
|
||||
LMIC.rssi = LMIC.rssi - 125 + 64; // RSSI [dBm] (-196...+63)
|
||||
} else if( flags & IRQ_LORA_RXTOUT_MASK ) {
|
||||
// indicate timeout
|
||||
LMIC.dataLen = 0;
|
||||
#if LMIC_DEBUG_LEVEL > 0
|
||||
ostime_t now2 = os_getTime();
|
||||
// ttn-esp32 change: fix printf for for ostime_t
|
||||
LMIC_DEBUG_PRINTF("rxtimeout: entry: %u rxtime: %u entry-rxtime: %d now-entry: %d rxtime-txend: %d\n", (unsigned)entry, (unsigned)LMIC.rxtime, entry - LMIC.rxtime, now2 - entry, LMIC.rxtime-LMIC.txend);
|
||||
#endif
|
||||
}
|
||||
// mask all radio IRQs
|
||||
writeReg(LORARegIrqFlagsMask, 0xFF);
|
||||
@ -845,10 +996,10 @@ void radio_irq_handler (u1_t dio, ostime_t t) {
|
||||
u1_t flags2 = readReg(FSKRegIrqFlags2);
|
||||
if( flags2 & IRQ_FSK2_PACKETSENT_MASK ) {
|
||||
// save exact tx time
|
||||
LMIC.txend = t;
|
||||
LMIC.txend = now;
|
||||
} else if( flags2 & IRQ_FSK2_PAYLOADREADY_MASK ) {
|
||||
// save exact rx time
|
||||
LMIC.rxtime = t;
|
||||
LMIC.rxtime = now;
|
||||
// read the PDU and inform the MAC that we received something
|
||||
LMIC.dataLen = readReg(FSKRegPayloadLength);
|
||||
// now read the FIFO
|
||||
@ -867,6 +1018,7 @@ void radio_irq_handler (u1_t dio, ostime_t t) {
|
||||
opmode(OPMODE_SLEEP);
|
||||
// run os job (use preset func ptr)
|
||||
os_setCallback(&LMIC.osjob, LMIC.osjob.func);
|
||||
#endif /* ! CFG_TxContinuousMode */
|
||||
}
|
||||
|
||||
void os_radio (u1_t mode) {
|
||||
@ -881,7 +1033,7 @@ void os_radio (u1_t mode) {
|
||||
// transmit frame now
|
||||
starttx(); // buf=LMIC.frame, len=LMIC.dataLen
|
||||
break;
|
||||
|
||||
|
||||
case RADIO_RX:
|
||||
// receive frame now (exactly at rxtime)
|
||||
startrx(RXMODE_SINGLE); // buf=LMIC.frame, time=LMIC.rxtime, timeout=LMIC.rxsyms
|
||||
|
Loading…
Reference in New Issue
Block a user