summaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2021-09-23 22:22:47 +0200
committerDaniel Friesel <derf@finalrewind.org>2021-09-23 22:22:47 +0200
commit8578e1ea7d078b60864b084094dbb02b6cac99c3 (patch)
tree19a02eef376f5b89c7044c48dcc0c0f43ea9d416 /src/app
parent30a29dcd0d064ab8403a9afb32c59800bb346840 (diff)
Import partially adapted MCCI LoRaWAN LMIC library. Needs further work.
Diffstat (limited to 'src/app')
-rw-r--r--src/app/lora32u4ii/Makefile.inc15
-rw-r--r--src/app/lora32u4ii/main.cc234
-rw-r--r--src/app/lora32u4ii/oslmic.h42
-rw-r--r--src/app/lora32u4ii/radio.h369
4 files changed, 161 insertions, 499 deletions
diff --git a/src/app/lora32u4ii/Makefile.inc b/src/app/lora32u4ii/Makefile.inc
index c201be2..f0ff22f 100644
--- a/src/app/lora32u4ii/Makefile.inc
+++ b/src/app/lora32u4ii/Makefile.inc
@@ -7,3 +7,18 @@
ifdef app
loop = 1
endif
+
+COMMON_FLAGS += -Isrc/lib/MCCI_LoRaWAN_LMIC_library/src
+
+C_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic.c
+C_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_eu868.c
+C_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_util.c
+C_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_eu_like.c
+C_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/lmic_channelshuffle.c
+C_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/oslmic.c
+C_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/lmic/radio.c
+C_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/aes/lmic.c
+C_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/aes/other.c
+
+CXX_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/hal/hal.cc
+CXX_TARGETS += src/lib/MCCI_LoRaWAN_LMIC_library/src/aes/ideetron/AES-128_V10.cc
diff --git a/src/app/lora32u4ii/main.cc b/src/app/lora32u4ii/main.cc
index b44652b..bb7cdae 100644
--- a/src/app/lora32u4ii/main.cc
+++ b/src/app/lora32u4ii/main.cc
@@ -8,16 +8,33 @@
#include "driver/stdout.h"
#include "driver/uptime.h"
#include "driver/adc.h"
-#include "driver/spi.h"
+
+/*
+ * Work in progress! Joining is sometimes successful, but that's about it.
+ * TX with user-defined payloads after joining doesn't appear to work yet.
+ */
#define CFG_eu868 1
#define CFG_sx1276_radio 1
+#define DISABLE_LMIC_FAILURE_TO
+
+#include <lmic.h>
+#include <hal/hal.h>
+
+static const u1_t PROGMEM APPEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
-#include "radio.h"
-#include "oslmic.h"
+static const u1_t PROGMEM DEVEUI[8]={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
-unsigned char txbuf[4];
-unsigned char rxbuf[4];
+static const u1_t PROGMEM APPKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}
+
+// Schedule TX every this many seconds (might become longer due to duty
+// cycle limitations).
+const unsigned TX_INTERVAL = 10;
+
+bool joined = false;
// DIYMall BSFrance LoRa32u4 II v1.3
// See also: arduino packages/adafruit/hardware/avr/1.4.13/variants/feather32u4/pins_arduino.h
@@ -25,95 +42,128 @@ unsigned char rxbuf[4];
// PB0 is also the !SS pin, so it must be configured as output in order to use SPI.
// PB5 "D9" <- Vbat/2 via voltage divider. Appears to also have a connection to the user LED
// PC7 "D13" -> User LED
-const GPIO::Pin rstpin = GPIO::pd4; // "D4" -> RST
-const GPIO::Pin cspin = GPIO::pb4; // "D8" -> NSS
-const GPIO::Pin dio0pin = GPIO::pe6; // "D7" <- DIO0 / IRQ
-const GPIO::Pin dio1pin = GPIO::pc6; // "D5" <- DIO1
-
-static void writeReg (u1_t addr, u1_t data) {
- txbuf[0] = addr | 0x80;
- txbuf[1] = data;
- gpio.write(cspin, 0);
- spi.xmit(2, txbuf, 0, rxbuf);
- gpio.write(cspin, 1);
-}
-
-static u1_t readReg (u1_t addr) {
- txbuf[0] = addr & 0x7f;
- gpio.write(cspin, 0);
- spi.xmit(1, txbuf, 2, rxbuf);
- gpio.write(cspin, 1);
- return rxbuf[1];
-}
-/*
-static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) {
- txbuf[0] = addr | 0x80;
- for (uint8_t i = 0; i < len; i++) {
- txbuf[i+1] = buf[i];
+const lmic_pinmap lmic_pins = {
+ .nss = GPIO::pb4,
+ .rxtx = LMIC_UNUSED_PIN,
+ .rst = GPIO::pd4,
+ .dio = {GPIO::pe6, GPIO::pc6, LMIC_UNUSED_PIN},
+};
+
+static osjob_t sendjob;
+
+void do_send(osjob_t* j){
+ uint16_t bat = adc.getVBat_mV(false);
+
+ // Check if there is not a current TX/RX job running
+ if (LMIC.opmode & OP_TXRXPEND) {
+ kout.pprint(PSTR("OP_TXRXPEND\n"));
+ } else {
+ // Prepare upstream data transmission at the next possible time.
+ LMIC_setTxData2(1, (uint8_t *)&bat, sizeof(bat), 0);
+ kout.pprint(PSTR("Packet queued\n"));
}
- spi.xmit(len+1, txbuf, 0, rxbuf);
+ // Next TX is scheduled after TX_COMPLETE event.
}
-static void readBuf (u1_t addr, xref2u1_t buf, u1_t len) {
- txbuf[0] = addr & 0x7f;
- spi.xmit(1, txbuf, len, buf);
-}
-*/
+void do_sleep(){
+ kout.pprint(PSTR("naptime\n"));
-static void writeOpmode(u1_t mode) {
- u1_t const maskedMode = mode & OPMODE_MASK;
- writeReg(RegOpMode, mode);
+ for(int i=0; i<75; i++){
+ arch.idle();
+ }
}
-static void opmode (u1_t mode) {
- writeOpmode((readReg(RegOpMode) & ~OPMODE_MASK) | mode);
-}
-
-
-
-bool radio_init()
-{
- // requestModuleActive(1); not required for sx yadayada
- gpio.output(cspin, 1);
-#ifdef CFG_sx1276_radio
- gpio.output(rstpin, 0);
-#else
- gpio.output(rstpin, 1);
-#endif
- arch.delay_ms(1);
- gpio.input(rstpin);
- gpio.write(rstpin, 0); // disable pull-up
- arch.delay_ms(5);
- opmode(OPMODE_SLEEP);
-
- u1_t v = readReg(RegVersion);
-#ifdef CFG_sx1276_radio
- if(v != 0x12 ) {
- kout << "Radio version mismatch: expected " << hex << 0x12 << ", got " << v << endl;
- return false;
- }
-#elif CFG_sx1272_radio
- if(v != 0x22) {
- kout << "Radio version mismatch: expected " << hex << 0x22 << ", got " << v << endl;
- return false;
- }
-#else
-#error Missing CFG_sx1272_radio/CFG_sx1276_radio
-#endif
- return true;
+void onEvent (ev_t ev) {
+ switch(ev) {
+ case EV_SCAN_TIMEOUT:
+ kout.pprint(PSTR("EV_SCAN_TIMEOUT\n"));
+ break;
+ case EV_JOINING:
+ kout.pprint(PSTR("EV_JOINING\n"));
+ break;
+ case EV_JOINED:
+ kout.pprint(PSTR("EV_JOINED\n"));
+ #if 1
+ {
+ u4_t netid = 0;
+ devaddr_t devaddr = 0;
+ u1_t nwkKey[16];
+ u1_t artKey[16];
+ LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
+ kout.pprint(PSTR("netid: "));
+ kout << dec << netid << endl;
+ kout.pprint(PSTR("devaddr: "));
+ kout << hex << devaddr << endl;
+ //Serial.print(PSTR("AppSKey: "));
+ for (size_t i=0; i<sizeof(artKey); ++i) {
+ if (i != 0) {
+ //Serial.print(PSTR("-"));
+ }
+ //printHex2(artKey[i]);
+ }
+ kout.pprint(PSTR(""));
+ //Serial.print(PSTR("NwkSKey: "));
+ for (size_t i=0; i<sizeof(nwkKey); ++i) {
+ if (i != 0) {
+ //Serial.print("-");
+ }
+ //printHex2(nwkKey[i]);
+ }
+ kout << endl;
+ }
+ #endif
+ joined = true;
+ break;
+ case EV_JOIN_FAILED:
+ kout.pprint(PSTR("EV_JOIN_FAILED\n"));
+ break;
+ case EV_TXCOMPLETE:
+ kout.pprint(PSTR("EV_TXCOMPLETE (includes waiting for RX windows)\n"));
+ // Schedule next transmission
+ if (joined) {
+ do_sleep();
+ do_send(&sendjob);
+ } else {
+ os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
+ }
+ break;
+ case EV_RESET:
+ kout.pprint(PSTR("EV_RESET\n"));
+ break;
+ case EV_RXCOMPLETE:
+ // data received in ping slot
+ kout.pprint(PSTR("EV_RXCOMPLETE\n"));
+ break;
+ case EV_LINK_DEAD:
+ kout.pprint(PSTR("EV_LINK_DEAD\n"));
+ break;
+ case EV_LINK_ALIVE:
+ kout.pprint(PSTR("EV_LINK_ALIVE\n"));
+ break;
+ case EV_TXSTART:
+ kout.pprint(PSTR("EV_TXSTART\n"));
+ break;
+ case EV_TXCANCELED:
+ kout.pprint(PSTR("EV_TXCANCELED\n"));
+ break;
+ case EV_RXSTART:
+ /* do not print anything -- it wrecks timing */
+ break;
+ case EV_JOIN_TXCOMPLETE:
+ kout.pprint(PSTR("EV_JOIN_TXCOMPLETE: no JoinAccept\n"));
+ break;
+
+ default:
+ kout.pprint(PSTR("Unknown event: "));
+ kout << (unsigned) ev;
+ break;
+ }
}
void loop(void)
{
- //gpio.led_toggle(1);
-#ifdef TIMER_S
- kout << dec << uptime.get_s() << endl;
-#else
- kout << "beep boop" << endl;
-#endif
- kout << "VCC = " << adc.getVCC_mV() << " mV" << endl;
- kout << "Vbat = " << adc.getVBat_mV(false) << " mV" << endl;
- gpio.led_toggle(0);
+ os_runloop_once();
+ gpio.led_toggle();
}
int main(void)
@@ -121,14 +171,22 @@ int main(void)
arch.setup();
gpio.setup();
kout.setup();
- spi.setup();
gpio.input(GPIO::pb5);
+ gpio.led_on();
- radio_init();
+ kout.pprint(PSTR("Hello, World!\n"));
+ kout.pprint(PSTR("Test, World!\n"));
- kout << "Hello, World!" << endl;
- kout << "Test, World!" << endl;
+ os_init();
+ LMIC_reset();
+ LMIC_setClockError(MAX_CLOCK_ERROR * 20 / 100);
+ LMIC_setAdrMode(0);
+ do_send(&sendjob);
+ while (1) {
+ os_runloop_once();
+ gpio.led_toggle();
+ }
arch.idle_loop();
return 0;
diff --git a/src/app/lora32u4ii/oslmic.h b/src/app/lora32u4ii/oslmic.h
deleted file mode 100644
index 8cdb91b..0000000
--- a/src/app/lora32u4ii/oslmic.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-/*
- * Copyright (c) 2014-2016 IBM Corporation.
- * Copyright (c) 2018, 2019 MCCI Corporation
- * Copyright (c) 2021 Daniel Friesel
- * 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.
- */
-
-#include <stdint.h>
-typedef uint8_t bit_t;
-typedef uint8_t u1_t;
-typedef int8_t s1_t;
-typedef uint16_t u2_t;
-typedef int16_t s2_t;
-typedef uint32_t u4_t;
-typedef int32_t s4_t;
-typedef unsigned int uint;
-typedef const char* str_t;
-
-
diff --git a/src/app/lora32u4ii/radio.h b/src/app/lora32u4ii/radio.h
deleted file mode 100644
index bc65405..0000000
--- a/src/app/lora32u4ii/radio.h
+++ /dev/null
@@ -1,369 +0,0 @@
-#pragma once
-/*
- * Copyright (c) 2014-2016 IBM Corporation.
- * Copyright (c) 2016-2019 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.
- */
-
-// ----------------------------------------
-// Registers Mapping
-// // -type- 1272 vs 1276
-#define RegFifo 0x00 // common
-#define RegOpMode 0x01 // common see below
-#define FSKRegBitrateMsb 0x02 // -
-#define FSKRegBitrateLsb 0x03 // -
-#define FSKRegFdevMsb 0x04 // -
-#define FSKRegFdevLsb 0x05 // -
-#define RegFrfMsb 0x06 // common FSK: 1272: 915; 1276: 434 MHz
-#define RegFrfMid 0x07 // common ditto
-#define RegFrfLsb 0x08 // common ditto
-#define RegPaConfig 0x09 // common see below, many diffs
-#define RegPaRamp 0x0A // common see below: bits 6..4 are diff
-#define RegOcp 0x0B // common -
-#define RegLna 0x0C // common bits 4..0 are diff.
-#define FSKRegRxConfig 0x0D // -
-#define LORARegFifoAddrPtr 0x0D
-#define FSKRegRssiConfig 0x0E // -
-#define LORARegFifoTxBaseAddr 0x0E
-#define FSKRegRssiCollision 0x0F // -
-#define LORARegFifoRxBaseAddr 0x0F
-#define FSKRegRssiThresh 0x10 // -
-#define LORARegFifoRxCurrentAddr 0x10
-#define FSKRegRssiValue 0x11 // -
-#define LORARegIrqFlagsMask 0x11
-#define FSKRegRxBw 0x12 // -
-#define LORARegIrqFlags 0x12
-#define FSKRegAfcBw 0x13 // -
-#define LORARegRxNbBytes 0x13
-#define FSKRegOokPeak 0x14 // -
-#define LORARegRxHeaderCntValueMsb 0x14
-#define FSKRegOokFix 0x15 // -
-#define LORARegRxHeaderCntValueLsb 0x15
-#define FSKRegOokAvg 0x16 // -
-#define LORARegRxPacketCntValueMsb 0x16
-#define LORARegRxpacketCntValueLsb 0x17
-#define LORARegModemStat 0x18
-#define LORARegPktSnrValue 0x19
-#define FSKRegAfcFei 0x1A // -
-#define LORARegPktRssiValue 0x1A
-#define FSKRegAfcMsb 0x1B // -
-#define LORARegRssiValue 0x1B
-#define FSKRegAfcLsb 0x1C // -
-#define LORARegHopChannel 0x1C
-#define FSKRegFeiMsb 0x1D // -
-#define LORARegModemConfig1 0x1D
-#define FSKRegFeiLsb 0x1E // -
-#define LORARegModemConfig2 0x1E
-#define FSKRegPreambleDetect 0x1F // -
-#define LORARegSymbTimeoutLsb 0x1F
-#define FSKRegRxTimeout1 0x20 // -
-#define LORARegPreambleMsb 0x20
-#define FSKRegRxTimeout2 0x21 // -
-#define LORARegPreambleLsb 0x21
-#define FSKRegRxTimeout3 0x22 // -
-#define LORARegPayloadLength 0x22
-#define FSKRegRxDelay 0x23 // -
-#define LORARegPayloadMaxLength 0x23
-#define FSKRegOsc 0x24 // -
-#define LORARegHopPeriod 0x24
-#define FSKRegPreambleMsb 0x25 // -
-#define LORARegFifoRxByteAddr 0x25
-#define FSKRegPreambleLsb 0x26 // -
-#define LORARegModemConfig3 0x26
-#define FSKRegSyncConfig 0x27 // -
-#define LORARegFeiMsb 0x28
-#define FSKRegSyncValue1 0x28 // -
-#define LORAFeiMib 0x29
-#define FSKRegSyncValue2 0x29 // -
-#define LORARegFeiLsb 0x2A
-#define FSKRegSyncValue3 0x2A // -
-#define FSKRegSyncValue4 0x2B // -
-#define LORARegRssiWideband 0x2C
-#define FSKRegSyncValue5 0x2C // -
-#define FSKRegSyncValue6 0x2D // -
-#define FSKRegSyncValue7 0x2E // -
-#define FSKRegSyncValue8 0x2F // -
-#define LORARegIffReq1 0x2F
-#define FSKRegPacketConfig1 0x30 // -
-#define LORARegIffReq2 0x30
-#define FSKRegPacketConfig2 0x31 // -
-#define LORARegDetectOptimize 0x31
-#define FSKRegPayloadLength 0x32 // -
-#define FSKRegNodeAdrs 0x33 // -
-#define LORARegInvertIQ 0x33
-#define FSKRegBroadcastAdrs 0x34 // -
-#define FSKRegFifoThresh 0x35 // -
-#define FSKRegSeqConfig1 0x36 // -
-#define LORARegHighBwOptimize1 0x36
-#define FSKRegSeqConfig2 0x37 // -
-#define LORARegDetectionThreshold 0x37
-#define FSKRegTimerResol 0x38 // -
-#define FSKRegTimer1Coef 0x39 // -
-#define LORARegSyncWord 0x39
-#define FSKRegTimer2Coef 0x3A // -
-#define LORARegHighBwOptimize2 0x3A
-#define FSKRegImageCal 0x3B // -
-#define FSKRegTemp 0x3C // -
-#define FSKRegLowBat 0x3D // -
-#define FSKRegIrqFlags1 0x3E // -
-#define FSKRegIrqFlags2 0x3F // -
-#define RegDioMapping1 0x40 // common
-#define RegDioMapping2 0x41 // common
-#define RegVersion 0x42 // common
-// #define RegAgcRef 0x43 // common
-// #define RegAgcThresh1 0x44 // common
-// #define RegAgcThresh2 0x45 // common
-// #define RegAgcThresh3 0x46 // common
-// #define RegPllHop 0x4B // common
-// #define RegTcxo 0x58 // common
-// #define RegPll 0x5C // common
-// #define RegPllLowPn 0x5E // common
-// #define RegFormerTemp 0x6C // common
-// #define RegBitRateFrac 0x70 // common
-
-#if defined(CFG_sx1276_radio)
-#define RegTcxo 0x4B // common different addresses, same bits
-#define RegPaDac 0x4D // common differnet addresses, same bits
-#elif defined(CFG_sx1272_radio)
-#define RegTcxo 0x58 // common
-#define RegPaDac 0x5A // common
-#endif
-
-#define RegTcxo_TcxoInputOn (1u << 4)
-
-// ----------------------------------------
-// spread factors and mode for RegModemConfig2
-#define SX1272_MC2_FSK 0x00
-#define SX1272_MC2_SF7 0x70
-#define SX1272_MC2_SF8 0x80
-#define SX1272_MC2_SF9 0x90
-#define SX1272_MC2_SF10 0xA0
-#define SX1272_MC2_SF11 0xB0
-#define SX1272_MC2_SF12 0xC0
-// bandwidth for RegModemConfig1
-#define SX1272_MC1_BW_125 0x00
-#define SX1272_MC1_BW_250 0x40
-#define SX1272_MC1_BW_500 0x80
-// coding rate for RegModemConfig1
-#define SX1272_MC1_CR_4_5 0x08
-#define SX1272_MC1_CR_4_6 0x10
-#define SX1272_MC1_CR_4_7 0x18
-#define SX1272_MC1_CR_4_8 0x20
-#define SX1272_MC1_IMPLICIT_HEADER_MODE_ON 0x04 // required for receive
-#define SX1272_MC1_RX_PAYLOAD_CRCON 0x02
-#define SX1272_MC1_LOW_DATA_RATE_OPTIMIZE 0x01 // mandated for SF11 and SF12
-// transmit power configuration for RegPaConfig
-#define SX1272_PAC_PA_SELECT_PA_BOOST 0x80
-#define SX1272_PAC_PA_SELECT_RFIO_PIN 0x00
-
-
-// sx1276 RegModemConfig1
-#define SX1276_MC1_BW_125 0x70
-#define SX1276_MC1_BW_250 0x80
-#define SX1276_MC1_BW_500 0x90
-#define SX1276_MC1_CR_4_5 0x02
-#define SX1276_MC1_CR_4_6 0x04
-#define SX1276_MC1_CR_4_7 0x06
-#define SX1276_MC1_CR_4_8 0x08
-
-#define SX1276_MC1_IMPLICIT_HEADER_MODE_ON 0x01
-
-#ifdef CFG_sx1276_radio
-# define SX127X_MC1_IMPLICIT_HEADER_MODE_ON SX1276_MC1_IMPLICIT_HEADER_MODE_ON
-#else
-# define SX127X_MC1_IMPLICIT_HEADER_MODE_ON SX1272_MC1_IMPLICIT_HEADER_MODE_ON
-#endif
-
-// transmit power configuration for RegPaConfig
-#define SX1276_PAC_PA_SELECT_PA_BOOST 0x80
-#define SX1276_PAC_PA_SELECT_RFIO_PIN 0x00
-#define SX1276_PAC_MAX_POWER_MASK 0x70
-
-// the bits to change for max power.
-#define SX127X_PADAC_POWER_MASK 0x07
-#define SX127X_PADAC_POWER_NORMAL 0x04
-#define SX127X_PADAC_POWER_20dBm 0x07
-
-// convert milliamperes to equivalent value for
-// RegOcp; delivers conservative value.
-#define SX127X_OCP_MAtoBITS(mA) \
- ((mA) < 45 ? 0 : \
- (mA) <= 120 ? ((mA) - 45) / 5 : \
- (mA) < 130 ? 0xF : \
- (mA) < 240 ? ((mA) - 130) / 10 + 0x10 : \
- 27)
-
-// bit in RegOcp that enables overcurrent protect.
-#define SX127X_OCP_ENA 0x20
-
-// sx1276 RegModemConfig2
-#define SX1276_MC2_RX_PAYLOAD_CRCON 0x04
-
-// sx1276 RegModemConfig3
-#define SX1276_MC3_LOW_DATA_RATE_OPTIMIZE 0x08
-#define SX1276_MC3_AGCAUTO 0x04
-
-// preamble for lora networks (nibbles swapped)
-#define LORA_MAC_PREAMBLE 0x34
-
-#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1 0x0A
-#ifdef CFG_sx1276_radio
-#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x70
-#elif CFG_sx1272_radio
-#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 and 5.5.5:
-#define SX1272_RSSI_ADJUST -139 // add to rssi value to get dB (LF)
-
-// per datasheet 5.5.3 and 5.5.5:
-#define SX1276_RSSI_ADJUST_LF -164 // add to rssi value to get dB (LF)
-#define SX1276_RSSI_ADJUST_HF -157 // add to rssi value to get dB (HF)
-
-#ifdef CFG_sx1276_radio
-# define SX127X_RSSI_ADJUST_LF SX1276_RSSI_ADJUST_LF
-# define SX127X_RSSI_ADJUST_HF SX1276_RSSI_ADJUST_HF
-#else
-# define SX127X_RSSI_ADJUST_LF SX1272_RSSI_ADJUST
-# define SX127X_RSSI_ADJUST_HF SX1272_RSSI_ADJUST
-#endif
-
-// 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
-#define OPMODE_SLEEP 0x00
-#define OPMODE_STANDBY 0x01
-#define OPMODE_FSTX 0x02
-#define OPMODE_TX 0x03
-#define OPMODE_FSRX 0x04
-#define OPMODE_RX 0x05
-#define OPMODE_RX_SINGLE 0x06
-#define OPMODE_CAD 0x07
-
-// ----------------------------------------
-// FSK opmode bits
-// bits 6:5 are the same for 1272 and 1276
-#define OPMODE_FSK_SX127x_ModulationType_FSK (0u << 5)
-#define OPMODE_FSK_SX127x_ModulationType_OOK (1u << 5)
-#define OPMODE_FSK_SX127x_ModulationType_MASK (3u << 5)
-
-// bits 4:3 are different for 1272
-#define OPMODE_FSK_SX1272_ModulationShaping_FSK_None (0u << 3)
-#define OPMODE_FSK_SX1272_ModulationShaping_FSK_BT1_0 (1u << 3)
-#define OPMODE_FSK_SX1272_ModulationShaping_FSK_BT0_5 (2u << 3)
-#define OPMODE_FSK_SX1272_ModulationShaping_FSK_BT0_3 (3u << 3)
-#define OPMODE_FSK_SX1272_ModulationShaping_OOK_None (0u << 3)
-#define OPMODE_FSK_SX1272_ModulationShaping_OOK_BR (1u << 3)
-#define OPMODE_FSK_SX1272_ModulationShaping_OOK_2BR (2u << 3)
-
-#define OPMODE_FSK_SX1272_ModulationShaping_MASK (3u << 3)
-
-// SX1276
-#define OPMODE_FSK_SX1276_LowFrequencyModeOn (1u << 3)
-
-// define the opmode bits apporpriate for the 127x in use.
-#if defined(CFG_sx1272_radio)
-# define OPMODE_FSK_SX127X_SETUP (OPMODE_FSK_SX127x_ModulationType_FSK | \
- OPMODE_FSK_SX1272_ModulationShaping_FSK_BT0_5)
-#elif defined(CFG_sx1276_radio)
-# define OPMODE_FSK_SX127X_SETUP (OPMODE_FSK_SX127x_ModulationType_FSK)
-#endif
-
-// ----------------------------------------
-// LoRa opmode bits
-#define OPMODE_LORA_SX127x_AccessSharedReg (1u << 6)
-#define OPMODE_LORA_SX1276_LowFrequencyModeOn (1u << 3)
-
-// ----------------------------------------
-// Bits masking the corresponding IRQs from the radio
-#define IRQ_LORA_RXTOUT_MASK 0x80
-#define IRQ_LORA_RXDONE_MASK 0x40
-#define IRQ_LORA_CRCERR_MASK 0x20
-#define IRQ_LORA_HEADER_MASK 0x10
-#define IRQ_LORA_TXDONE_MASK 0x08
-#define IRQ_LORA_CDDONE_MASK 0x04
-#define IRQ_LORA_FHSSCH_MASK 0x02
-#define IRQ_LORA_CDDETD_MASK 0x01
-
-#define IRQ_FSK1_MODEREADY_MASK 0x80
-#define IRQ_FSK1_RXREADY_MASK 0x40
-#define IRQ_FSK1_TXREADY_MASK 0x20
-#define IRQ_FSK1_PLLLOCK_MASK 0x10
-#define IRQ_FSK1_RSSI_MASK 0x08
-#define IRQ_FSK1_TIMEOUT_MASK 0x04
-#define IRQ_FSK1_PREAMBLEDETECT_MASK 0x02
-#define IRQ_FSK1_SYNCADDRESSMATCH_MASK 0x01
-#define IRQ_FSK2_FIFOFULL_MASK 0x80
-#define IRQ_FSK2_FIFOEMPTY_MASK 0x40
-#define IRQ_FSK2_FIFOLEVEL_MASK 0x20
-#define IRQ_FSK2_FIFOOVERRUN_MASK 0x10
-#define IRQ_FSK2_PACKETSENT_MASK 0x08
-#define IRQ_FSK2_PAYLOADREADY_MASK 0x04
-#define IRQ_FSK2_CRCOK_MASK 0x02
-#define IRQ_FSK2_LOWBAT_MASK 0x01
-
-// ----------------------------------------
-// DIO function mappings D0D1D2D3
-#define MAP_DIO0_LORA_RXDONE 0x00 // 00------
-#define MAP_DIO0_LORA_TXDONE 0x40 // 01------
-#define MAP_DIO1_LORA_RXTOUT 0x00 // --00----
-#define MAP_DIO1_LORA_NOP 0x30 // --11----
-#define MAP_DIO2_LORA_NOP 0x0C // ----11--
-
-#define MAP_DIO0_FSK_READY 0x00 // 00------ (packet sent / payload ready)
-#define MAP_DIO1_FSK_NOP 0x30 // --11----
-#define MAP_DIO2_FSK_TXNOP 0x04 // ----01--
-#define MAP_DIO2_FSK_TIMEOUT 0x08 // ----10--
-
-
-// FSK IMAGECAL defines
-#define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F
-#define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80
-#define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default
-
-#define RF_IMAGECAL_IMAGECAL_MASK 0xBF
-#define RF_IMAGECAL_IMAGECAL_START 0x40
-
-#define RF_IMAGECAL_IMAGECAL_RUNNING 0x20
-#define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default
-
-// LNA gain constant. Bits 4..0 have different meaning for 1272 and 1276, but
-// by chance, the bit patterns we use are the same.
-#ifdef CFG_sx1276_radio
-#define LNA_RX_GAIN (0x20|0x3)
-#elif CFG_sx1272_radio
-#define LNA_RX_GAIN (0x20|0x03)
-#else
-#error Missing CFG_sx1272_radio/CFG_sx1276_radio
-#endif