Basic config functions

This commit is contained in:
Martijn Scheepers
2020-01-23 10:54:08 +01:00
parent 184e5a5747
commit 6043fe125f
2 changed files with 367 additions and 424 deletions

View File

@@ -1,3 +1,6 @@
//Arduino Board = Arduino Pro or Pro Mini
//Processor = Atmega328p (3.3v 8MHz)
#include <Arduino.h>
#include <SPI.h>
//#include <EEPROM.h>
@@ -17,18 +20,6 @@
#define EEPROM_CONFIG_OFFSET 0
#ifdef ABP
// LoRaWAN NwkSKey, network session key
// This should be in big-endian (aka msb).
static const PROGMEM u1_t NWKSKEY[16] = {0xE9, 0x4C, 0x5A, 0xD6, 0xA1, 0x16, 0xAF, 0x4A, 0xB5, 0x2B, 0xB8, 0xAC, 0x3D, 0xCD, 0x60, 0x2C};
// LoRaWAN AppSKey, application session key
// This should also be in big-endian (aka msb).
static const u1_t PROGMEM APPSKEY[16] = {0x44, 0x49, 0x19, 0x26, 0x74, 0x0E, 0x59, 0x00, 0x2F, 0xF5, 0x8D, 0xE7, 0x00, 0x91, 0x1D, 0x40};
// LoRaWAN end-device address (DevAddr)
// The library converts the address to network byte order as needed, so this should be in big-endian (aka msb) too.
static const u4_t DEVADDR = 0x2601119A;
// These callbacks are only used in over-the-air activation, so they are
// left empty here (we cannot leave them out completely unless
// DISABLE_JOIN is set in arduino-lmic/project_config/lmic_project_config.h,
@@ -38,100 +29,112 @@ void os_getDevEui(u1_t *buf) {}
void os_getDevKey(u1_t *buf) {}
#endif
#ifdef OTAA
struct config_t
{
const u1_t APPEUI[8] = {}; // = { 0xB8, 0x34, 0x02, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
const u1_t DEVEUI[8] = {}; // = { 0xBC, 0xAD, 0x24, 0x90, 0xB5, 0x52, 0xD6, 0xA8 };
const u1_t APPKEY[16] = {}; // = { 0xE9, 0x64, 0x28, 0x39, 0x10, 0x47, 0x4B, 0x65, 0x35, 0xF3, 0x51, 0x59, 0xC8, 0xDF, 0x9A, 0x22 };
//ABP
// LoRaWAN NwkSKey, network session key, This should be in big-endian (aka msb).
const u1_t NWKSKEY[16] = {}; // = {0xE9, 0x4C, 0x5A, 0xD6, 0xA1, 0x16, 0xAF, 0x4A, 0xB5, 0x2B, 0xB8, 0xAC, 0x3D, 0xCD, 0x60, 0x2C};
// LoRaWAN AppSKey, application session key, This should also be in big-endian (aka msb).
const u1_t APPSKEY[16] = {}; //= {0x44, 0x49, 0x19, 0x26, 0x74, 0x0E, 0x59, 0x00, 0x2F, 0xF5, 0x8D, 0xE7, 0x00, 0x91, 0x1D, 0x40};
// LoRaWAN end-device address (DevAddr), The library converts the address to network byte order as needed, so this should be in big-endian (aka msb) to
const u4_t DEVADDR = {}; //= 0x2601119A;
//OTAA
// This EUI must be in little-endian format, so least-significant-byte
// first. When copying an EUI from ttnctl output, this means to reverse
// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
// 0x70.
//const u1_t APPEUI[8] = {}; // = { 0xB8, 0x34, 0x02, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
const u1_t APPEUI[8] = { 0xB8, 0x34, 0x02, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
// This should also be in little endian format, see above.
//const u1_t DEVEUI[8] = {}; // = { 0xBC, 0xAD, 0x24, 0x90, 0xB5, 0x52, 0xD6, 0xA8 };
const u1_t DEVEUI[8] = { 0xBC, 0xAD, 0x24, 0x90, 0xB5, 0x52, 0xD6, 0xA8 };
// This key should be in big endian format (or, since it is not really a
// number but a block of memory, endianness does not really apply). In
// practice, a key taken from ttnctl can be copied as-is.
//const u1_t APPKEY[16] = {}; // = { 0xE9, 0x64, 0x28, 0x39, 0x10, 0x47, 0x4B, 0x65, 0x35, 0xF3, 0x51, 0x59, 0xC8, 0xDF, 0x9A, 0x22 };
const u1_t APPKEY[16] = { 0xE9, 0x64, 0x28, 0x39, 0x10, 0x47, 0x4B, 0x65, 0x35, 0xF3, 0x51, 0x59, 0xC8, 0xDF, 0x9A, 0x22 };
} configuration;
// This EUI must be in little-endian format, so least-significant-byte
// first. When copying an EUI from ttnctl output, this means to reverse
// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
// 0x70.
//static const u1_t PROGMEM APPEUI[8]={ 0xB8, 0x34, 0x02, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
//void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
void os_getArtEui(u1_t *buf) { memcpy(buf, configuration.APPEUI, 8); }
// This should also be in little endian format, see above.
//static const u1_t PROGMEM DEVEUI[8]={ 0xBC, 0xAD, 0x24, 0x90, 0xB5, 0x52, 0xD6, 0xA8 };
//void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
void os_getDevEui(u1_t *buf) { memcpy(buf, configuration.DEVEUI, 8); }
// This key should be in big endian format (or, since it is not really a
// number but a block of memory, endianness does not really apply). In
// practice, a key taken from ttnctl can be copied as-is.
//static const u1_t PROGMEM APPKEY[16] = { 0xE9, 0x64, 0x28, 0x39, 0x10, 0x47, 0x4B, 0x65, 0x35, 0xF3, 0x51, 0x59, 0xC8, 0xDF, 0x9A, 0x22 };
//void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}
void os_getDevKey(u1_t *buf) { memcpy(buf, configuration.APPKEY, 16); }
#ifdef OTAA
void os_getArtEui(u1_t *buf) {
memcpy(buf, configuration.APPEUI, 8);
}
void os_getDevEui(u1_t *buf) {
memcpy(buf, configuration.DEVEUI, 8);
}
void os_getDevKey(u1_t *buf) {
memcpy(buf, configuration.APPKEY, 16);
}
#endif
static uint8_t mydata[] = "X";
static osjob_t sendjob;
const unsigned TX_INTERVAL = 60; //seconds
const lmic_pinmap lmic_pins = {
.nss = 10, // chip select on feather (rf95module) CS
.rxtx = LMIC_UNUSED_PIN,
.rst = 9, // reset pin
.dio = {2, 5, LMIC_UNUSED_PIN}, // DIO0, DIO1, DIO2
.nss = 10, // chip select on feather (rf95module) CS
.rxtx = LMIC_UNUSED_PIN,
.rst = 9, // reset pin
.dio = {2, 5, LMIC_UNUSED_PIN}, // DIO0, DIO1, DIO2
};
void onEvent(ev_t ev)
{
Serial.print(os_getTime());
Serial.print(": ");
switch (ev)
{
Serial.print(os_getTime());
Serial.print(": ");
switch (ev)
{
case EV_SCAN_TIMEOUT:
Serial.println(F("EV_SCAN_TIMEOUT"));
break;
Serial.println(F("EV_SCAN_TIMEOUT"));
break;
case EV_BEACON_FOUND:
Serial.println(F("EV_BEACON_FOUND"));
break;
Serial.println(F("EV_BEACON_FOUND"));
break;
case EV_BEACON_MISSED:
Serial.println(F("EV_BEACON_MISSED"));
break;
Serial.println(F("EV_BEACON_MISSED"));
break;
case EV_BEACON_TRACKED:
Serial.println(F("EV_BEACON_TRACKED"));
break;
Serial.println(F("EV_BEACON_TRACKED"));
break;
case EV_JOINING:
Serial.println(F("EV_JOINING"));
break;
Serial.println(F("EV_JOINING"));
break;
case EV_JOINED:
Serial.println(F("EV_JOINED"));
Serial.println(F("EV_JOINED"));
{
u4_t netid = 0;
devaddr_t devaddr = 0;
u1_t nwkKey[16];
u1_t artKey[16];
LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
Serial.print(F("netid: "));
Serial.println(netid, DEC);
Serial.print(F("devaddr: "));
Serial.println(devaddr, HEX);
Serial.print(F("artKey: "));
for (size_t i = 0; i < sizeof(artKey); ++i)
{
u4_t netid = 0;
devaddr_t devaddr = 0;
u1_t nwkKey[16];
u1_t artKey[16];
LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
Serial.print(F("netid: "));
Serial.println(netid, DEC);
Serial.print(F("devaddr: "));
Serial.println(devaddr, HEX);
Serial.print(F("artKey: "));
for (size_t i = 0; i < sizeof(artKey); ++i)
{
Serial.print(artKey[i], HEX);
}
Serial.println("");
Serial.print(F("nwkKey: "));
for (size_t i = 0; i < sizeof(nwkKey); ++i)
{
Serial.print(nwkKey[i], HEX);
}
Serial.println("");
Serial.print(artKey[i], HEX);
}
// 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;
Serial.println("");
Serial.print(F("nwkKey: "));
for (size_t i = 0; i < sizeof(nwkKey); ++i)
{
Serial.print(nwkKey[i], HEX);
}
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.
@@ -139,42 +142,42 @@ void onEvent(ev_t ev)
|| case EV_RFU1:
|| Serial.println(F("EV_RFU1"));
|| break;
*/
*/
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
Serial.println(F("EV_REJOIN_FAILED"));
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;
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;
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
Serial.println(F("EV_LINK_ALIVE"));
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
@@ -182,357 +185,131 @@ void onEvent(ev_t ev)
|| case EV_SCAN_FOUND:
|| Serial.println(F("EV_SCAN_FOUND"));
|| break;
*/
*/
case EV_TXSTART:
Serial.println(F("EV_TXSTART"));
break;
Serial.println(F("EV_TXSTART"));
break;
case EV_RXSTART:
Serial.println(F("EV_RXSTART"));
break;
Serial.println(F("EV_RXSTART"));
break;
case EV_JOIN_TXCOMPLETE:
Serial.println(F("EV_JOIN_TXCOMPLETE"));
break;
Serial.println(F("EV_JOIN_TXCOMPLETE"));
break;
default:
Serial.print(F("Unknown event: "));
Serial.println((unsigned)ev);
break;
}
Serial.print(F("Unknown event: "));
Serial.println((unsigned)ev);
break;
}
}
void do_send(osjob_t *j)
{
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND)
{
Serial.println(F("OP_TXRXPEND, not sending"));
}
else
{
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata) - 1, 0);
Serial.println(F("Packet queued"));
}
// Next TX is scheduled after TX_COMPLETE event.
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND)
{
Serial.println(F("OP_TXRXPEND, not sending"));
}
else
{
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata) - 1, 0);
Serial.println(F("Packet queued"));
}
// Next TX is scheduled after TX_COMPLETE event.
}
//Timer 1 interrupt callback
ISR(TIMER1_COMPA_vect)
{
digitalWrite(LED_GREEN, !digitalRead(LED_GREEN));
digitalWrite(LED_ORANGE, !digitalRead(LED_ORANGE));
digitalWrite(LED_RED, !digitalRead(LED_RED));
digitalWrite(LED_GREEN, !digitalRead(LED_GREEN));
digitalWrite(LED_ORANGE, !digitalRead(LED_ORANGE));
digitalWrite(LED_RED, !digitalRead(LED_RED));
}
void setup()
{
Serial.begin(9600, SERIAL_8N1);
Serial.println(F("Starting"));
Serial.begin(9600, SERIAL_8N1);
Serial.println(F("Starting"));
pinMode(LED_RED, OUTPUT);
pinMode(LED_ORANGE, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_RED, OUTPUT);
pinMode(LED_ORANGE, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(INPUT_1, INPUT_PULLUP);
pinMode(INPUT_2, INPUT_PULLUP);
pinMode(INPUT_1, INPUT_PULLUP);
pinMode(INPUT_2, INPUT_PULLUP);
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_ORANGE, LOW);
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_ORANGE, LOW);
digitalWrite(LED_RED, HIGH);
// initialize timer1 1 sec
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 31250; // compare match register 16MHz/256/2Hz
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts
// initialize timer1 1 sec
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 31250; // compare match register 16MHz/256/2Hz
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts
//eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
eeprom_read_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
//eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
eeprom_read_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
// Use with Arduino Pro Mini ATmega328P 3.3V 8 MHz
// Let LMIC compensate for +/- 1% clock error
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
// Use with Arduino Pro Mini ATmega328P 3.3V 8 MHz
// Let LMIC compensate for +/- 1% clock error
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
#ifdef ABP
// Set static session parameters. Instead of dynamically establishing a session
// by joining the network, precomputed session parameters are be provided.
// Set static session parameters. Instead of dynamically establishing a session
// by joining the network, precomputed session parameters are be provided.
#ifdef PROGMEM
// On AVR, these values are stored in flash and only copied to RAM
// once. Copy them to a temporary buffer here, LMIC_setSession will
// copy them into a buffer of its own again.
uint8_t appskey[sizeof(APPSKEY)];
uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession(0x13, DEVADDR, nwkskey, appskey);
// On AVR, these values are stored in flash and only copied to RAM
// once. Copy them to a temporary buffer here, LMIC_setSession will
// copy them into a buffer of its own again.
uint8_t appskey[sizeof(configuration.APPSKEY)];
uint8_t nwkskey[sizeof(configuration.NWKSKEY)];
memcpy_P(appskey, configuration.APPSKEY, sizeof(configuration.APPSKEY));
memcpy_P(nwkskey, configuration.NWKSKEY, sizeof(configuration.NWKSKEY));
LMIC_setSession(0x13, configuration.DEVADDR, nwkskey, appskey);
#else
// If not running an AVR with PROGMEM, just use the arrays directly
LMIC_setSession(0x13, DEVADDR, NWKSKEY, APPSKEY);
// If not running an AVR with PROGMEM, just use the arrays directly
LMIC_setSession(0x13, configuration.DEVADDR, configuration.NWKSKEY, configuration.APPSKEY);
#endif
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
// Disable link check validation
LMIC_setLinkCheckMode(0);
// Disable link check validation
LMIC_setLinkCheckMode(0);
// TTN uses SF9 for its RX2 window.
LMIC.dn2Dr = DR_SF9;
// TTN uses SF9 for its RX2 window.
LMIC.dn2Dr = DR_SF9;
// Set data rate and transmit power for uplink
LMIC_setDrTxpow(DR_SF7, 14);
// Set data rate and transmit power for uplink
LMIC_setDrTxpow(DR_SF7, 14);
#endif
// Start job
do_send(&sendjob);
// Start job
do_send(&sendjob);
}
#define CMDLINELEN 20
char cmdline[CMDLINELEN];
int idx = 0;
int timeout = 0;
#define STX 0x02
#define ETX 0x03
void loop()
{
timeout++;
if (timeout == 2000)
{
idx = 0;
memset(cmdline, '\0', CMDLINELEN);
timeout = 0;
}
if (Serial.available() > 0)
{
int incomingByte = Serial.read();
if (incomingByte == STX)
{
//Serial.println("STX");
idx = 0;
}
else if (incomingByte == ETX)
{
//Serial.println("ETX");
//Serial.println(cmdline);
char buf[17];
switch (cmdline[0])
{
case 'a': //get DevEUI
memcpy(buf, configuration.DEVEUI, 8);
buf[9] = '\0';
Serial.write(STX);
//Serial.println(F("get deveui"));
Serial.write('a');
Serial.write(buf, 8);
Serial.write(ETX);
break;
case 'b': //get appEUI
memcpy(buf, configuration.APPEUI, 8);
buf[9] = '\0';
Serial.write(STX);
//Serial.println(F("get appeui"));
Serial.write('b');
Serial.write(buf, 8);
Serial.write(ETX);
break;
case 'c': //get appkey
memcpy(buf, configuration.APPKEY, 16);
buf[17] = '\0';
Serial.write(STX);
//Serial.println(F("get appkey"));
Serial.write('c');
Serial.write(buf, 16);
Serial.write(ETX);
break;
case 'd': //get devaddr
memset(buf, 0x00, 8);
buf[9] = '\0';
Serial.write(STX);
//Serial.println(F("get devaddr"));
Serial.write('d');
Serial.write(buf, 8);
Serial.write(ETX);
break;
case 'e': //get nwkskey
memset(buf, 0x00, 16);
buf[9] = '\0';
Serial.write(STX);
//Serial.println(F("get nwkskey"));
Serial.write('e');
Serial.write(buf, 16);
Serial.write(ETX);
break;
case 'f': //get appskey
memset(buf, 0x00, 16);
buf[9] = '\0';
Serial.write(STX);
//Serial.println(F("get appskey"));
Serial.write('f');
Serial.write(buf, 16);
Serial.write(ETX);
break;
case 'A': //Set DevEUI
Serial.println(F("set deveui"));
// Serial.println(&cmdline[1]);
// memcpy(configuration.DEVEUI, &cmdline[1], 8);
break;
case 'B': //Set appEUI
Serial.println(F("set appeui"));
// Serial.println(&cmdline[1]);
// memcpy(configuration.APPEUI, &cmdline[1], 8);
break;
case 'C': //Set APPKEY
Serial.println(F("set appkey"));
// Serial.println(&cmdline[1]);
// memcpy(configuration.APPKEY, &cmdline[1], 16);
break;
case 'D': //Set devaddr
Serial.println(F("set devaddr"));
// Serial.println(&cmdline[1]);
break;
case 'E': //Set NwkSKey
Serial.println(F("set nwkskey"));
// Serial.println(&cmdline[1]);
break;
case 'F': //Set appskey
Serial.println(F("set appskey"));
// Serial.println(&cmdline[1]);
break;
}
memset(cmdline, '\0', CMDLINELEN);
idx = 0;
}
else if (idx >= CMDLINELEN)
{
memset(cmdline, '\0', CMDLINELEN);
idx = 0;
}
else
{
cmdline[idx] = incomingByte;
idx++;
//Serial.println(incomingByte, HEX);
}
// say what you got:
//Serial.print("I received: ");
//Serial.println(incomingByte, HEX);
//Serial.write(incomingByte);
//Serial.println(Serial.available());
//timeout = 0;
//cmdline[idx] = Serial.read();
//if (cmdline[idx] == '\n' || cmdline[idx] == '\r')
//{
// Serial.println("End of line");
//}
//idx++;
//cmdline[idx] = '\0';
//Serial.print(F("RX="));
//Serial.println(cmdline);
//Serial.print(strlen(cmdline));
//Serial.write(strlen(cmdline));
// for (size_t i = 0; i < strlen(cmdline); i++)
// {
// //Serial.print(cmdline[i]);
// Serial.write(cmdline[i]);
// }
//Serial.println();
// if (cmdline[(idx - 1)] == '\n' || cmdline[(idx - 1)] == '\r')
// {
// char buf[17];
// switch (cmdline[0])
// {
// case 'a': //get DevEUI
// Serial.println(F("get deveui"));
// memcpy(buf, configuration.DEVEUI, 8);
// buf[9] = '\0';
// Serial.println(buf);
// break;
// case 'b': //get appEUI
// Serial.println(F("get appeui"));
// memcpy(buf, configuration.APPEUI, 8);
// buf[9] = '\0';
// Serial.println(buf);
// break;
// case 'c': //get appkey
// Serial.println(F("get appkey"));
// memcpy(buf, configuration.APPKEY, 16);
// buf[17] = '\0';
// Serial.println(buf);
// break;
// case 'd': //get devaddr
// Serial.println(F("get devaddr"));
// break;
// case 'e': //get nwkskey
// Serial.println(F("get nmkskey"));
// break;
// case 'f': //get appskey
// Serial.println(F("get appskey"));
// break;
// case 'A': //Set DevEUI
// Serial.println(F("set deveui"));
// Serial.println(&cmdline[1]);
// memcpy(configuration.DEVEUI, &cmdline[1], 8);
// break;
// case 'B': //Set appEUI
// Serial.println(F("set appeui"));
// Serial.println(&cmdline[1]);
// memcpy(configuration.APPEUI, &cmdline[1], 8);
// break;
// case 'C': //Set APPKEY
// Serial.println(F("set appkey"));
// Serial.println(&cmdline[1]);
// memcpy(configuration.APPKEY, &cmdline[1], 16);
// break;
// case 'D': //Set devaddr
// Serial.println(F("set devaddr"));
// Serial.println(&cmdline[1]);
// break;
// case 'E': //Set NwkSKey
// Serial.println(F("set nwkskey"));
// Serial.println(&cmdline[1]);
// break;
// case 'F': //Set appskey
// Serial.println(F("set appskey"));
// Serial.println(&cmdline[1]);
// break;
// }
// memset(cmdline, '\0', CMDLINELEN);
// idx = 0;
// }
}
os_runloop_once();
}
receiveSerialCommand();
os_runloop_once();
}

View File

@@ -0,0 +1,166 @@
#define CMDLINELEN 20
#define STX 0x02
#define ETX 0x03
char cmdline[CMDLINELEN];
int idx = 0;
int timeout = 0;
void receiveSerialCommand() {
timeout++;
if (timeout == 2000)
{
idx = 0;
memset(cmdline, '\0', CMDLINELEN);
timeout = 0;
}
if (Serial.available() > 0)
{
int incomingByte = Serial.read();
if (incomingByte == STX)
{
idx = 0;
}
else if (incomingByte == ETX)
{
checkSerialCommand(cmdline);
memset(cmdline, '\0', CMDLINELEN);
idx = 0;
}
else if (idx >= CMDLINELEN)
{
memset(cmdline, '\0', CMDLINELEN);
idx = 0;
}
else
{
cmdline[idx] = incomingByte;
idx++;
}
}
}
void sendDevEUI() {
char buf[11];
memcpy(buf, configuration.DEVEUI, 8);
buf[9] = '\0';
Serial.write(STX);
Serial.write('a');
Serial.write(buf, 8);
Serial.write(ETX);
}
void sendAppEUI() {
char buf[11];
memcpy(buf, configuration.APPEUI, 8);
buf[9] = '\0';
Serial.write(STX);
Serial.write('b');
Serial.write(buf, 8);
Serial.write(ETX);
}
void sendAppKey() {
char buf[19];
memcpy(buf, configuration.APPKEY, 16);
buf[17] = '\0';
Serial.write(STX);
Serial.write('c');
Serial.write(buf, 16);
Serial.write(ETX);
}
void sendDevAddr() {
char buf[11];
memset(buf, configuration.DEVADDR, 8);
buf[9] = '\0';
Serial.write(STX);
Serial.write('d');
Serial.write(buf, 8);
Serial.write(ETX);
}
void sendNwksKey() {
char buf[19];
memset(buf, configuration.NWKSKEY, 16);
buf[9] = '\0';
Serial.write(STX);
Serial.write('e');
Serial.write(buf, 16);
Serial.write(ETX);
}
void sendAppsKey() {
char buf[19];
memset(buf, configuration.APPSKEY, 16);
buf[9] = '\0';
Serial.write(STX);
Serial.write('f');
Serial.write(buf, 16);
Serial.write(ETX);
}
void checkSerialCommand(char cmd[]) {
char buf[17];
switch (cmd[0])
{
case 'a': //get DevEUI
sendDevEUI();
break;
case 'b': //get appEUI
sendAppEUI();
break;
case 'c': //get appkey
sendAppKey();
break;
case 'd': //get devaddr
sendDevAddr();
break;
case 'e': //get nwkskey
sendNwksKey();
break;
case 'f': //get appskey
sendAppsKey();
break;
case '?': //ABP or ATAA
Serial.write(STX);
Serial.write('?');
#ifdef ABP
Serial.write('A');
#endif
#ifdef OTAA
Serial.write('O');
#endif
Serial.write(ETX);
break;
case 'A': //Set DevEUI
memcpy(configuration.DEVEUI, &cmdline[1], 8);
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
sendDevEUI();
break;
case 'B': //Set appEUI
memcpy(configuration.APPEUI, &cmdline[1], 8);
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
sendAppEUI();
break;
case 'C': //Set APPKEY
memcpy(configuration.APPKEY, &cmdline[1], 16);
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
sendAppKey();
break;
case 'D': //Set devaddr
memcpy(configuration.DEVADDR, &cmdline[1], 8);
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
sendDevAddr();
break;
case 'E': //Set NwkSKey
memcpy(configuration.NWKSKEY, &cmdline[1], 16);
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
sendNwksKey();
break;
case 'F': //Set appskey
memcpy(configuration.APPSKEY, &cmdline[1], 16);
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
sendAppsKey();
break;
}
}