Add formatting (#7)

* commit default clang-format

* apply clang-format

* add formatting guidelines
pull/9/head
Louis Thiery 2020-02-18 12:24:41 -08:00 zatwierdzone przez GitHub
rodzic 95b9865313
commit 063710e94a
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
4 zmienionych plików z 554 dodań i 432 usunięć

121
.clang-format 100644
Wyświetl plik

@ -0,0 +1,121 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseTab: Never
...

Wyświetl plik

@ -9,6 +9,10 @@ our way or a bug to report:
repo](https://github.com/helium/longfi-arduino). Include a repo](https://github.com/helium/longfi-arduino). Include a
write up of the PR with details on what it does. write up of the PR with details on what it does.
* **Formatting Code**: Please apply clang-format to any PRs. From the
root of the repository:
`find . -regex '.*\.\(cpp\|hpp\|cu\|c\|h\|ino\)' -exec clang-format -i {} \;`
* **Reporting Bugs**: Open an issue [against this * **Reporting Bugs**: Open an issue [against this
repo](https://github.com/helium/longfi-arduino/issues) with as much repo](https://github.com/helium/longfi-arduino/issues) with as much
detail as you can. At the very least you'll include steps to detail as you can. At the very least you'll include steps to
@ -19,4 +23,4 @@ collaboration, and contributors are expected to adhere to the
[Contributor Covenant Code of [Contributor Covenant Code of
Conduct](http://contributor-covenant.org/). Conduct](http://contributor-covenant.org/).
Above all, thank you for taking the time to be a part of the Helium community. Above all, thank you for taking the time to be a part of the Helium community.

Wyświetl plik

@ -15,7 +15,6 @@
* *
*******************************************************************************/ *******************************************************************************/
/******************************************************************************* /*******************************************************************************
* *
* For Helium developers, follow the Arduino Quickstart guide: * For Helium developers, follow the Arduino Quickstart guide:
@ -27,34 +26,34 @@
* *
*******************************************************************************/ *******************************************************************************/
#include <lmic.h> #include <Adafruit_GPS.h>
#include <arduino_lmic_hal_configuration.h> #include <SPI.h>
#include <arduino_lmic.h>
#include <arduino_lmic_hal_boards.h> #include <arduino_lmic_hal_boards.h>
#include <arduino_lmic_hal_configuration.h>
#include <arduino_lmic_lorawan_compliance.h> #include <arduino_lmic_lorawan_compliance.h>
#include <arduino_lmic_user_configuration.h> #include <arduino_lmic_user_configuration.h>
#include <arduino_lmic.h>
#include <hal/hal.h> #include <hal/hal.h>
#include <SPI.h> #include <lmic.h>
#include <Adafruit_GPS.h>
#define GPSSerial Serial1 #define GPSSerial Serial1
// Connect to the GPS on the hardware port // Connect to the GPS on the hardware port
Adafruit_GPS GPS(&GPSSerial); Adafruit_GPS GPS(&GPSSerial);
// This is the "App EUI" in Helium. Make sure it is little-endian (lsb). // This is the "App EUI" in Helium. Make sure it is little-endian (lsb).
static const u1_t PROGMEM APPEUI[8]= { FILL_ME_IN }; static const u1_t PROGMEM APPEUI[8] = {FILL_ME_IN};
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);} void os_getArtEui(u1_t *buf) { memcpy_P(buf, APPEUI, 8); }
// This should also be in little endian format // This should also be in little endian format
// These are user configurable values and Helium console permits anything // These are user configurable values and Helium console permits anything
static const u1_t PROGMEM DEVEUI[8]= { 0x48, 0x65, 0x6c, 0x69, 0x75, 0x6d, 0x20, 0x20 }; static const u1_t PROGMEM DEVEUI[8] = {0x48, 0x65, 0x6c, 0x69,
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);} 0x75, 0x6d, 0x20, 0x20};
void os_getDevEui(u1_t *buf) { memcpy_P(buf, DEVEUI, 8); }
// This is the "App Key" in Helium. It is big-endian (msb). // This is the "App Key" in Helium. It is big-endian (msb).
static const u1_t PROGMEM APPKEY[16] = { FILL_ME_IN }; static const u1_t PROGMEM APPKEY[16] = {FILL_ME_IN};
void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);} void os_getDevKey(u1_t *buf) { memcpy_P(buf, APPKEY, 16); }
static uint8_t mydata[] = "Hello, world!"; static uint8_t mydata[] = "Hello, world!";
static osjob_t sendjob; static osjob_t sendjob;
@ -76,229 +75,230 @@ const lmic_pinmap lmic_pins = {
.rst = 4, .rst = 4,
.dio = {3, 6, LMIC_UNUSED_PIN}, .dio = {3, 6, LMIC_UNUSED_PIN},
.rxtx_rx_active = 0, .rxtx_rx_active = 0,
.rssi_cal = 8, // LBT cal for the Adafruit Feather M0 LoRa, in dB .rssi_cal = 8, // LBT cal for the Adafruit Feather M0 LoRa, in dB
.spi_freq = 8000000, .spi_freq = 8000000,
}; };
#elif defined(MCCI_CATENA_4610) #elif defined(MCCI_CATENA_4610)
#include "arduino_lmic_hal_boards.h" #include "arduino_lmic_hal_boards.h"
const lmic_pinmap lmic_pins = *Arduino_LMIC::GetPinmap_Catena4610(); const lmic_pinmap lmic_pins = *Arduino_LMIC::GetPinmap_Catena4610();
#else #else
# error "Unknown target" #error "Unknown target"
#endif #endif
void onEvent (ev_t ev) { void onEvent(ev_t ev) {
Serial.print(os_getTime()); Serial.print(os_getTime());
Serial.print(": "); Serial.print(": ");
switch(ev) { switch (ev) {
case EV_SCAN_TIMEOUT: case EV_SCAN_TIMEOUT:
Serial.println(F("EV_SCAN_TIMEOUT")); Serial.println(F("EV_SCAN_TIMEOUT"));
break; break;
case EV_BEACON_FOUND: case EV_BEACON_FOUND:
Serial.println(F("EV_BEACON_FOUND")); Serial.println(F("EV_BEACON_FOUND"));
break; break;
case EV_BEACON_MISSED: case EV_BEACON_MISSED:
Serial.println(F("EV_BEACON_MISSED")); Serial.println(F("EV_BEACON_MISSED"));
break; break;
case EV_BEACON_TRACKED: case EV_BEACON_TRACKED:
Serial.println(F("EV_BEACON_TRACKED")); Serial.println(F("EV_BEACON_TRACKED"));
break; break;
case EV_JOINING: case EV_JOINING:
Serial.println(F("EV_JOINING")); Serial.println(F("EV_JOINING"));
break; break;
case EV_JOIN_TXCOMPLETE: case EV_JOIN_TXCOMPLETE:
Serial.println(F("EV_JOIN_TXCOMPLETE")); Serial.println(F("EV_JOIN_TXCOMPLETE"));
break; break;
case EV_JOINED: case EV_JOINED:
Serial.println(F("EV_JOINED")); Serial.println(F("EV_JOINED"));
{ {
u4_t netid = 0; u4_t netid = 0;
devaddr_t devaddr = 0; devaddr_t devaddr = 0;
u1_t nwkKey[16]; u1_t nwkKey[16];
u1_t artKey[16]; u1_t artKey[16];
LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
Serial.print("netid: "); Serial.print("netid: ");
Serial.println(netid, DEC); Serial.println(netid, DEC);
Serial.print("devaddr: "); Serial.print("devaddr: ");
Serial.println(devaddr, HEX); Serial.println(devaddr, HEX);
Serial.print("artKey: "); Serial.print("artKey: ");
for (size_t i=0; i<sizeof(artKey); ++i) { for (size_t i = 0; i < sizeof(artKey); ++i) {
if (i != 0) if (i != 0)
Serial.print("-"); Serial.print("-");
Serial.print(artKey[i], HEX); Serial.print(artKey[i], HEX);
} }
Serial.println(""); Serial.println("");
Serial.print("nwkKey: "); Serial.print("nwkKey: ");
for (size_t i=0; i<sizeof(nwkKey); ++i) { for (size_t i = 0; i < sizeof(nwkKey); ++i) {
if (i != 0) if (i != 0)
Serial.print("-"); Serial.print("-");
Serial.print(nwkKey[i], HEX); Serial.print(nwkKey[i], HEX);
} }
Serial.println(""); Serial.println("");
}
// Disable link check validation (automatically enabled
// during join, but because slow data rates change max TX
// size, we don't use it in this example.
LMIC_setLinkCheckMode(0);
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_RFU1:
|| Serial.println(F("EV_RFU1"));
|| break;
*/
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F("Received ack"));
if (LMIC.dataLen) {
Serial.println(F("Received "));
Serial.println(LMIC.dataLen);
Serial.println(F(" bytes of payload"));
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
break;
case EV_LOST_TSYNC:
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_SCAN_FOUND:
|| Serial.println(F("EV_SCAN_FOUND"));
|| break;
*/
case EV_TXSTART:
Serial.println(F("EV_TXSTART"));
break;
default:
Serial.print(F("Unknown event: "));
Serial.println((unsigned) ev);
break;
} }
// Disable link check validation (automatically enabled
// during join, but because slow data rates change max TX
// size, we don't use it in this example.
LMIC_setLinkCheckMode(0);
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_RFU1:
|| Serial.println(F("EV_RFU1"));
|| break;
*/
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F("Received ack"));
if (LMIC.dataLen) {
Serial.println(F("Received "));
Serial.println(LMIC.dataLen);
Serial.println(F(" bytes of payload"));
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL),
do_send);
break;
case EV_LOST_TSYNC:
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_SCAN_FOUND:
|| Serial.println(F("EV_SCAN_FOUND"));
|| break;
*/
case EV_TXSTART:
Serial.println(F("EV_TXSTART"));
break;
default:
Serial.print(F("Unknown event: "));
Serial.println((unsigned)ev);
break;
}
} }
void do_send(osjob_t* j){ void do_send(osjob_t *j) {
// Check if there is not a current TX/RX job running // Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) { if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending")); Serial.println(F("OP_TXRXPEND, not sending"));
} else { } else {
// Prepare upstream data transmission at the next possible time.
static uint8_t payload[32];
uint8_t idx = 0;
uint32_t data;
if (GPS.newNMEAreceived()) { // Prepare upstream data transmission at the next possible time.
GPS.parse(GPS.lastNMEA()); static uint8_t payload[32];
} uint8_t idx = 0;
uint32_t data;
if (GPS.fix) {
Serial.println(GPS.latitudeDegrees); if (GPS.newNMEAreceived()) {
Serial.println(GPS.longitudeDegrees); GPS.parse(GPS.lastNMEA());
Serial.println(GPS.altitude + 0.5);
data = (int)(GPS.latitudeDegrees * 1E7);
payload[idx++] = data >> 24;
payload[idx++] = data >> 16;
payload[idx++] = data >> 8;
payload[idx++] = data;
data = (int)(GPS.longitudeDegrees * 1E7);
payload[idx++] = data >> 24;
payload[idx++] = data >> 16;
payload[idx++] = data >> 8;
payload[idx++] = data;
data = (int)(GPS.altitude + 0.5);
payload[idx++] = data >> 8;
payload[idx++] = data;
data = (int)(GPS.speed);
payload[idx++] = data >> 8;
payload[idx++] = data;
} else {
for (idx=0; idx<12; idx++) {
payload[idx] = 0;
}
}
Serial.println(F("Packet queued"));
LMIC_setTxData2(1, payload, idx, 0);
} }
if (GPS.fix) {
Serial.println(GPS.latitudeDegrees);
Serial.println(GPS.longitudeDegrees);
Serial.println(GPS.altitude + 0.5);
data = (int)(GPS.latitudeDegrees * 1E7);
payload[idx++] = data >> 24;
payload[idx++] = data >> 16;
payload[idx++] = data >> 8;
payload[idx++] = data;
data = (int)(GPS.longitudeDegrees * 1E7);
payload[idx++] = data >> 24;
payload[idx++] = data >> 16;
payload[idx++] = data >> 8;
payload[idx++] = data;
data = (int)(GPS.altitude + 0.5);
payload[idx++] = data >> 8;
payload[idx++] = data;
data = (int)(GPS.speed);
payload[idx++] = data >> 8;
payload[idx++] = data;
} else {
for (idx = 0; idx < 12; idx++) {
payload[idx] = 0;
}
}
Serial.println(F("Packet queued"));
LMIC_setTxData2(1, payload, idx, 0);
}
} }
void setup() { void setup() {
delay(5000); delay(5000);
while (! Serial) while (!Serial)
; ;
Serial.begin(9600); Serial.begin(9600);
Serial.println(F("Starting")); Serial.println(F("Starting"));
#if defined(ARDUINO_DISCO_L072CZ_LRWAN1) #if defined(ARDUINO_DISCO_L072CZ_LRWAN1)
SPI.setMOSI(RADIO_MOSI_PORT); SPI.setMOSI(RADIO_MOSI_PORT);
SPI.setMISO(RADIO_MISO_PORT); SPI.setMISO(RADIO_MISO_PORT);
SPI.setSCLK(RADIO_SCLK_PORT); SPI.setSCLK(RADIO_SCLK_PORT);
SPI.setSSEL(RADIO_NSS_PORT); SPI.setSSEL(RADIO_NSS_PORT);
// SPI.begin(); // SPI.begin();
#endif #endif
#ifdef VCC_ENABLE #ifdef VCC_ENABLE
// For Pinoccio Scout boards // For Pinoccio Scout boards
pinMode(VCC_ENABLE, OUTPUT); pinMode(VCC_ENABLE, OUTPUT);
digitalWrite(VCC_ENABLE, HIGH); digitalWrite(VCC_ENABLE, HIGH);
delay(1000); delay(1000);
#endif #endif
// LMIC init // LMIC init
os_init(); os_init();
// Reset the MAC state. Session and pending data transfers will be discarded. // Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset(); LMIC_reset();
// allow much more clock error than the X/1000 default. See: // allow much more clock error than the X/1000 default. See:
// https://github.com/mcci-catena/arduino-lorawan/issues/74#issuecomment-462171974 // https://github.com/mcci-catena/arduino-lorawan/issues/74#issuecomment-462171974
// https://github.com/mcci-catena/arduino-lmic/commit/42da75b56#diff-16d75524a9920f5d043fe731a27cf85aL633 // https://github.com/mcci-catena/arduino-lmic/commit/42da75b56#diff-16d75524a9920f5d043fe731a27cf85aL633
// the X/1000 means an error rate of 0.1%; the above issue discusses using values up to 10%. // the X/1000 means an error rate of 0.1%; the above issue discusses using
// so, values from 10 (10% error, the most lax) to 1000 (0.1% error, the most strict) can be used. // values up to 10%. so, values from 10 (10% error, the most lax) to 1000
LMIC_setClockError(1 * MAX_CLOCK_ERROR / 40); // (0.1% error, the most strict) can be used.
LMIC_setClockError(1 * MAX_CLOCK_ERROR / 40);
LMIC_setLinkCheckMode(0);
LMIC_setDrTxpow(DR_SF8, 20);
LMIC_selectSubBand(6);
GPS.begin(9600); LMIC_setLinkCheckMode(0);
// Only interrested in GGA, no antenna status LMIC_setDrTxpow(DR_SF8, 20);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); LMIC_selectSubBand(6);
GPS.sendCommand(PGCMD_NOANTENNA);
// Update every second
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
// Start job (sending automatically starts OTAA too) GPS.begin(9600);
do_send(&sendjob); // Only interrested in GGA, no antenna status
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PGCMD_NOANTENNA);
// Update every second
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
// Start job (sending automatically starts OTAA too)
do_send(&sendjob);
} }
void loop() { void loop() {
GPS.read(); GPS.read();
os_runloop_once(); os_runloop_once();
} }

Wyświetl plik

@ -15,7 +15,6 @@
* *
*******************************************************************************/ *******************************************************************************/
/******************************************************************************* /*******************************************************************************
* *
* For Helium developers, follow the Arduino Quickstart guide: * For Helium developers, follow the Arduino Quickstart guide:
@ -27,27 +26,28 @@
* *
*******************************************************************************/ *******************************************************************************/
#include <lmic.h> #include <SPI.h>
#include <arduino_lmic_hal_configuration.h> #include <arduino_lmic.h>
#include <arduino_lmic_hal_boards.h> #include <arduino_lmic_hal_boards.h>
#include <arduino_lmic_hal_configuration.h>
#include <arduino_lmic_lorawan_compliance.h> #include <arduino_lmic_lorawan_compliance.h>
#include <arduino_lmic_user_configuration.h> #include <arduino_lmic_user_configuration.h>
#include <arduino_lmic.h>
#include <hal/hal.h> #include <hal/hal.h>
#include <SPI.h> #include <lmic.h>
// This is the "App EUI" in Helium. Make sure it is little-endian (lsb). // This is the "App EUI" in Helium. Make sure it is little-endian (lsb).
static const u1_t PROGMEM APPEUI[8]= { FILL_ME_IN }; static const u1_t PROGMEM APPEUI[8] = {FILL_ME_IN};
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);} void os_getArtEui(u1_t *buf) { memcpy_P(buf, APPEUI, 8); }
// This should also be in little endian format // This should also be in little endian format
// These are user configurable values and Helium console permits anything // These are user configurable values and Helium console permits anything
static const u1_t PROGMEM DEVEUI[8]= { 0x48, 0x65, 0x6c, 0x69, 0x75, 0x6d, 0x20, 0x20 }; static const u1_t PROGMEM DEVEUI[8] = {0x48, 0x65, 0x6c, 0x69,
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);} 0x75, 0x6d, 0x20, 0x20};
void os_getDevEui(u1_t *buf) { memcpy_P(buf, DEVEUI, 8); }
// This is the "App Key" in Helium. It is big-endian (msb). // This is the "App Key" in Helium. It is big-endian (msb).
static const u1_t PROGMEM APPKEY[16] = { FILL_ME_IN }; static const u1_t PROGMEM APPKEY[16] = {FILL_ME_IN};
void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);} void os_getDevKey(u1_t *buf) { memcpy_P(buf, APPKEY, 16); }
static uint8_t mydata[] = "Hello, world!"; static uint8_t mydata[] = "Hello, world!";
static osjob_t sendjob; static osjob_t sendjob;
@ -69,7 +69,7 @@ const lmic_pinmap lmic_pins = {
.rst = 4, .rst = 4,
.dio = {3, 6, LMIC_UNUSED_PIN}, .dio = {3, 6, LMIC_UNUSED_PIN},
.rxtx_rx_active = 0, .rxtx_rx_active = 0,
.rssi_cal = 8, // LBT cal for the Adafruit Feather M0 LoRa, in dB .rssi_cal = 8, // LBT cal for the Adafruit Feather M0 LoRa, in dB
.spi_freq = 8000000, .spi_freq = 8000000,
}; };
#elif defined(ARDUINO_AVR_FEATHER32U4) #elif defined(ARDUINO_AVR_FEATHER32U4)
@ -83,24 +83,26 @@ const lmic_pinmap lmic_pins = {
.rst = 4, .rst = 4,
.dio = {7, 6, LMIC_UNUSED_PIN}, .dio = {7, 6, LMIC_UNUSED_PIN},
.rxtx_rx_active = 0, .rxtx_rx_active = 0,
.rssi_cal = 8, // LBT cal for the Adafruit Feather 32U4 LoRa, in dB .rssi_cal = 8, // LBT cal for the Adafruit Feather 32U4 LoRa, in dB
.spi_freq = 1000000, .spi_freq = 1000000,
}; };
#elif defined(ARDUINO_CATENA_4551) #elif defined(ARDUINO_CATENA_4551)
// Pin mapping for Murata module / Catena 4551 // Pin mapping for Murata module / Catena 4551
const lmic_pinmap lmic_pins = { const lmic_pinmap lmic_pins = {
.nss = 7, .nss = 7,
.rxtx = 29, .rxtx = 29,
.rst = 8, .rst = 8,
.dio = { 25, // DIO0 (IRQ) is D25 .dio =
26, // DIO1 is D26 {
27, // DIO2 is D27 25, // DIO0 (IRQ) is D25
}, 26, // DIO1 is D26
.rxtx_rx_active = 1, 27, // DIO2 is D27
.rssi_cal = 10, },
.spi_freq = 8000000 // 8MHz .rxtx_rx_active = 1,
.rssi_cal = 10,
.spi_freq = 8000000 // 8MHz
}; };
#elif defined(MCCI_CATENA_4610) #elif defined(MCCI_CATENA_4610)
#include "arduino_lmic_hal_boards.h" #include "arduino_lmic_hal_boards.h"
const lmic_pinmap lmic_pins = *Arduino_LMIC::GetPinmap_Catena4610(); const lmic_pinmap lmic_pins = *Arduino_LMIC::GetPinmap_Catena4610();
#elif defined(ARDUINO_DISCO_L072CZ_LRWAN1) #elif defined(ARDUINO_DISCO_L072CZ_LRWAN1)
@ -109,221 +111,216 @@ const HalPinmap_t GetPinmap_Disco_L072cz_Lrwan1();
} }
const lmic_pinmap lmic_pins = Arduino_LMIC::GetPinmap_Disco_L072cz_Lrwan1(); const lmic_pinmap lmic_pins = Arduino_LMIC::GetPinmap_Disco_L072cz_Lrwan1();
#else #else
# error "Unknown target" #error "Unknown target"
#endif #endif
void onEvent (ev_t ev) { void onEvent(ev_t ev) {
Serial.print(os_getTime()); Serial.print(os_getTime());
Serial.print(": "); Serial.print(": ");
switch(ev) { switch (ev) {
case EV_SCAN_TIMEOUT: case EV_SCAN_TIMEOUT:
Serial.println(F("EV_SCAN_TIMEOUT")); Serial.println(F("EV_SCAN_TIMEOUT"));
break; break;
case EV_BEACON_FOUND: case EV_BEACON_FOUND:
Serial.println(F("EV_BEACON_FOUND")); Serial.println(F("EV_BEACON_FOUND"));
break; break;
case EV_BEACON_MISSED: case EV_BEACON_MISSED:
Serial.println(F("EV_BEACON_MISSED")); Serial.println(F("EV_BEACON_MISSED"));
break; break;
case EV_BEACON_TRACKED: case EV_BEACON_TRACKED:
Serial.println(F("EV_BEACON_TRACKED")); Serial.println(F("EV_BEACON_TRACKED"));
break; break;
case EV_JOINING: case EV_JOINING:
Serial.println(F("EV_JOINING")); Serial.println(F("EV_JOINING"));
break; break;
case EV_JOIN_TXCOMPLETE: case EV_JOIN_TXCOMPLETE:
Serial.println(F("EV_JOIN_TXCOMPLETE")); Serial.println(F("EV_JOIN_TXCOMPLETE"));
break; break;
case EV_JOINED: case EV_JOINED:
Serial.println(F("EV_JOINED")); Serial.println(F("EV_JOINED"));
{ {
u4_t netid = 0; u4_t netid = 0;
devaddr_t devaddr = 0; devaddr_t devaddr = 0;
u1_t nwkKey[16]; u1_t nwkKey[16];
u1_t artKey[16]; u1_t artKey[16];
LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
Serial.print("netid: "); Serial.print("netid: ");
Serial.println(netid, DEC); Serial.println(netid, DEC);
Serial.print("devaddr: "); Serial.print("devaddr: ");
Serial.println(devaddr, HEX); Serial.println(devaddr, HEX);
Serial.print("artKey: "); Serial.print("artKey: ");
for (size_t i=0; i<sizeof(artKey); ++i) { for (size_t i = 0; i < sizeof(artKey); ++i) {
if (i != 0) if (i != 0)
Serial.print("-"); Serial.print("-");
Serial.print(artKey[i], HEX); Serial.print(artKey[i], HEX);
} }
Serial.println(""); Serial.println("");
Serial.print("nwkKey: "); Serial.print("nwkKey: ");
for (size_t i=0; i<sizeof(nwkKey); ++i) { for (size_t i = 0; i < sizeof(nwkKey); ++i) {
if (i != 0) if (i != 0)
Serial.print("-"); Serial.print("-");
Serial.print(nwkKey[i], HEX); Serial.print(nwkKey[i], HEX);
} }
Serial.println(""); Serial.println("");
}
// Disable link check validation (automatically enabled
// during join, but because slow data rates change max TX
// size, we don't use it in this example.
LMIC_setLinkCheckMode(0);
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_RFU1:
|| Serial.println(F("EV_RFU1"));
|| break;
*/
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F("Received ack"));
if (LMIC.dataLen) {
Serial.println(F("Received "));
Serial.println(LMIC.dataLen);
Serial.println(F(" bytes of payload"));
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
break;
case EV_LOST_TSYNC:
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_SCAN_FOUND:
|| Serial.println(F("EV_SCAN_FOUND"));
|| break;
*/
case EV_TXSTART:
Serial.println(F("EV_TXSTART"));
break;
default:
Serial.print(F("Unknown event: "));
Serial.println((unsigned) ev);
break;
} }
// Disable link check validation (automatically enabled
// during join, but because slow data rates change max TX
// size, we don't use it in this example.
LMIC_setLinkCheckMode(0);
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_RFU1:
|| Serial.println(F("EV_RFU1"));
|| break;
*/
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F("Received ack"));
if (LMIC.dataLen) {
Serial.println(F("Received "));
Serial.println(LMIC.dataLen);
Serial.println(F(" bytes of payload"));
}
// Schedule next transmission
os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL),
do_send);
break;
case EV_LOST_TSYNC:
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_SCAN_FOUND:
|| Serial.println(F("EV_SCAN_FOUND"));
|| break;
*/
case EV_TXSTART:
Serial.println(F("EV_TXSTART"));
break;
default:
Serial.print(F("Unknown event: "));
Serial.println((unsigned)ev);
break;
}
} }
void do_send(osjob_t* j){ void do_send(osjob_t *j) {
// Check if there is not a current TX/RX job running // Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) { if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending")); Serial.println(F("OP_TXRXPEND, not sending"));
} else { } else {
// Prepare upstream data transmission at the next possible time. // Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0); LMIC_setTxData2(1, mydata, sizeof(mydata) - 1, 0);
Serial.println(F("Packet queued")); Serial.println(F("Packet queued"));
} }
// Next TX is scheduled after TX_COMPLETE event. // Next TX is scheduled after TX_COMPLETE event.
} }
void setup() { void setup() {
delay(5000); delay(5000);
while (! Serial) while (!Serial)
; ;
Serial.begin(9600); Serial.begin(9600);
Serial.println(F("Starting")); Serial.println(F("Starting"));
#if defined(ARDUINO_DISCO_L072CZ_LRWAN1) #if defined(ARDUINO_DISCO_L072CZ_LRWAN1)
SPI.setMOSI(RADIO_MOSI_PORT); SPI.setMOSI(RADIO_MOSI_PORT);
SPI.setMISO(RADIO_MISO_PORT); SPI.setMISO(RADIO_MISO_PORT);
SPI.setSCLK(RADIO_SCLK_PORT); SPI.setSCLK(RADIO_SCLK_PORT);
SPI.setSSEL(RADIO_NSS_PORT); SPI.setSSEL(RADIO_NSS_PORT);
// SPI.begin(); // SPI.begin();
#endif #endif
#ifdef VCC_ENABLE #ifdef VCC_ENABLE
// For Pinoccio Scout boards // For Pinoccio Scout boards
pinMode(VCC_ENABLE, OUTPUT); pinMode(VCC_ENABLE, OUTPUT);
digitalWrite(VCC_ENABLE, HIGH); digitalWrite(VCC_ENABLE, HIGH);
delay(1000); delay(1000);
#endif #endif
// LMIC init // LMIC init
os_init(); os_init();
// Reset the MAC state. Session and pending data transfers will be discarded. // Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset(); LMIC_reset();
// allow much more clock error than the X/1000 default. See: // allow much more clock error than the X/1000 default. See:
// https://github.com/mcci-catena/arduino-lorawan/issues/74#issuecomment-462171974 // https://github.com/mcci-catena/arduino-lorawan/issues/74#issuecomment-462171974
// https://github.com/mcci-catena/arduino-lmic/commit/42da75b56#diff-16d75524a9920f5d043fe731a27cf85aL633 // https://github.com/mcci-catena/arduino-lmic/commit/42da75b56#diff-16d75524a9920f5d043fe731a27cf85aL633
// the X/1000 means an error rate of 0.1%; the above issue discusses using values up to 10%. // the X/1000 means an error rate of 0.1%; the above issue discusses using
// so, values from 10 (10% error, the most lax) to 1000 (0.1% error, the most strict) can be used. // values up to 10%. so, values from 10 (10% error, the most lax) to 1000
LMIC_setClockError(1 * MAX_CLOCK_ERROR / 40); // (0.1% error, the most strict) can be used.
LMIC_setClockError(1 * MAX_CLOCK_ERROR / 40);
LMIC_setLinkCheckMode(0); LMIC_setLinkCheckMode(0);
LMIC_setDrTxpow(DR_SF8, 20); LMIC_setDrTxpow(DR_SF8, 20);
LMIC_selectSubBand(6); LMIC_selectSubBand(6);
// Start job (sending automatically starts OTAA too) // Start job (sending automatically starts OTAA too)
do_send(&sendjob); do_send(&sendjob);
} }
void loop() { void loop() { os_runloop_once(); }
os_runloop_once();
}
namespace Arduino_LMIC { namespace Arduino_LMIC {
class HalConfiguration_Disco_L072cz_Lrwan1_t : public HalConfiguration_t class HalConfiguration_Disco_L072cz_Lrwan1_t : public HalConfiguration_t {
{ public:
public: enum DIGITAL_PINS : uint8_t {
enum DIGITAL_PINS : uint8_t PIN_SX1276_NSS = 37,
{ PIN_SX1276_NRESET = 33,
PIN_SX1276_NSS = 37, PIN_SX1276_DIO0 = 38,
PIN_SX1276_NRESET = 33, PIN_SX1276_DIO1 = 39,
PIN_SX1276_DIO0 = 38, PIN_SX1276_DIO2 = 40,
PIN_SX1276_DIO1 = 39, PIN_SX1276_RXTX = 21,
PIN_SX1276_DIO2 = 40, };
PIN_SX1276_RXTX = 21,
};
virtual bool queryUsingTcxo(void) override { return false; }; virtual bool queryUsingTcxo(void) override { return false; };
}; };
// save some typing by bringing the pin numbers into scope // save some typing by bringing the pin numbers into scope
static HalConfiguration_Disco_L072cz_Lrwan1_t myConfig; static HalConfiguration_Disco_L072cz_Lrwan1_t myConfig;
static const HalPinmap_t myPinmap = static const HalPinmap_t myPinmap = {
{ .nss = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_NSS,
.nss = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_NSS, .rxtx = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_RXTX,
.rxtx = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_RXTX, .rst = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_NRESET,
.rst = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_NRESET,
.dio = {HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO0, .dio =
HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO1, {
HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO2, HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO0,
}, HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO1,
.rxtx_rx_active = 1, HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO2,
.rssi_cal = 10, },
.spi_freq = 8000000, /* 8MHz */ .rxtx_rx_active = 1,
.pConfig = &myConfig .rssi_cal = 10,
}; .spi_freq = 8000000, /* 8MHz */
.pConfig = &myConfig};
const HalPinmap_t GetPinmap_Disco_L072cz_Lrwan1(void) const HalPinmap_t GetPinmap_Disco_L072cz_Lrwan1(void) { return myPinmap; }
{
return myPinmap;
}
}; // end namespace Arduino_LMIC }; // end namespace Arduino_LMIC