Added support for all Semtech LoRa modules (SX1272/73/76/77/78/79)
This commit is contained in:
parent
c2b1826410
commit
8d8ab76f5a
20 changed files with 1272 additions and 1139 deletions
45
keywords.txt
45
keywords.txt
|
@ -14,7 +14,11 @@ ESP8266 KEYWORD1
|
|||
HC05 KEYWORD1
|
||||
RF69 KEYWORD1
|
||||
SX1272 KEYWORD1
|
||||
SX1273 KEYWORD1
|
||||
SX1276 KEYWORD1
|
||||
SX1277 KEYWORD1
|
||||
SX1278 KEYWORD1
|
||||
SX1279 KEYWORD1
|
||||
XBee KEYWORD1
|
||||
|
||||
Bandwidth KEYWORD1
|
||||
|
@ -39,8 +43,9 @@ getDestinationStr KEYWORD2
|
|||
setSourceStr KEYWORD2
|
||||
setDestinationStr KEYWORD2
|
||||
copyInto KEYWORD2
|
||||
setPacketData KEYWORD2
|
||||
|
||||
# SX1278/SX1272 + RF69
|
||||
# SX1272/73/76/77/78/79 + RF69
|
||||
dataRate KEYWORD2
|
||||
lastPacketRSSI KEYWORD2
|
||||
begin KEYWORD2
|
||||
|
@ -51,6 +56,9 @@ standby KEYWORD2
|
|||
setBandwidth KEYWORD2
|
||||
setSpreadingFactor KEYWORD2
|
||||
setCodingRate KEYWORD2
|
||||
setFrequency KEYWORD2
|
||||
setSyncWord KEYWORD2
|
||||
setOutputPower KEYWORD2
|
||||
|
||||
# ESP8266
|
||||
join KEYWORD2
|
||||
|
@ -74,31 +82,9 @@ setPanId KEYWORD2
|
|||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
BW_7_80_KHZ LITERAL1
|
||||
BW_10_40_KHZ LITERAL1
|
||||
BW_15_60_KHZ LITERAL1
|
||||
BW_20_80_KHZ LITERAL1
|
||||
BW_31_25_KHZ LITERAL1
|
||||
BW_41_70_KHZ LITERAL1
|
||||
BW_62_50_KHZ LITERAL1
|
||||
BW_125_00_KHZ LITERAL1
|
||||
BW_250_00_KHZ LITERAL1
|
||||
BW_500_00_KHZ LITERAL1
|
||||
|
||||
SF_6 LITERAL1
|
||||
SF_7 LITERAL1
|
||||
SF_8 LITERAL1
|
||||
SF_9 LITERAL1
|
||||
SF_10 LITERAL1
|
||||
SF_11 LITERAL1
|
||||
SF_12 LITERAL1
|
||||
|
||||
CR_4_5 LITERAL1
|
||||
CR_4_6 LITERAL1
|
||||
CR_4_7 LITERAL1
|
||||
CR_4_8 LITERAL1
|
||||
|
||||
ERR_NONE LITERAL1
|
||||
ERR_UNKNOWN LITERAL1
|
||||
|
||||
ERR_CHIP_NOT_FOUND LITERAL1
|
||||
ERR_EEPROM_NOT_INITIALIZED LITERAL1
|
||||
ERR_PACKET_TOO_LONG LITERAL1
|
||||
|
@ -109,10 +95,19 @@ ERR_INVALID_BANDWIDTH LITERAL1
|
|||
ERR_INVALID_SPREADING_FACTOR LITERAL1
|
||||
ERR_INVALID_CODING_RATE LITERAL1
|
||||
ERR_INVALID_BIT_RANGE LITERAL1
|
||||
ERR_INVALID_FREQUENCY LITERAL1
|
||||
ERR_INVALID_OUTPUT_POWER LITERAL1
|
||||
PREAMBLE_DETECTED LITERAL1
|
||||
CHANNEL_FREE LITERAL1
|
||||
|
||||
ERR_AT_FAILED LITERAL1
|
||||
ERR_URL_MALFORMED LITERAL1
|
||||
ERR_RESPONSE_MALFORMED_AT LITERAL1
|
||||
ERR_RESPONSE_MALFORMED LITERAL1
|
||||
ERR_MQTT_CONN_VERSION_REJECTED LITERAL1
|
||||
ERR_MQTT_CONN_ID_REJECTED LITERAL1
|
||||
ERR_MQTT_CONN_SERVER_UNAVAILABLE LITERAL1
|
||||
ERR_MQTT_CONN_BAD_USERNAME_PASSWORD LITERAL1
|
||||
ERR_MQTT_CONN_NOT_AUTHORIZED LITERAL1
|
||||
|
||||
ERR_CMD_MODE_FAILED LITERAL1
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
#include "modules/HC05.h"
|
||||
#include "modules/RF69.h"
|
||||
#include "modules/SX1272.h"
|
||||
#include "modules/SX1273.h"
|
||||
#include "modules/SX1276.h"
|
||||
#include "modules/SX1277.h"
|
||||
#include "modules/SX1278.h"
|
||||
#include "modules/SX1279.h"
|
||||
#include "modules/XBee.h"
|
||||
|
||||
#define KITE_CS_A 10
|
||||
|
|
|
@ -136,8 +136,9 @@ uint8_t Module::SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t
|
|||
}
|
||||
|
||||
uint8_t currentValue = SPIreadRegister(reg);
|
||||
uint8_t newValue = currentValue & ((0b11111111 << (msb + 1)) & (0b11111111 >> (8 - lsb)));
|
||||
SPIwriteRegister(reg, newValue | value);
|
||||
uint8_t mask = ~((0b11111111 << (msb + 1)) | (0b11111111 >> (8 - lsb)));
|
||||
uint8_t newValue = (currentValue & ~mask) | (value & mask);
|
||||
SPIwriteRegister(reg, newValue);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
|
|
177
src/Packet.cpp
177
src/Packet.cpp
|
@ -5,174 +5,177 @@ Packet::Packet(void) {
|
|||
getLoRaAddress(src);
|
||||
|
||||
uint8_t dest[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint8_t dat[240];
|
||||
uint8_t* dat;
|
||||
uint8_t len = 0;
|
||||
|
||||
init(src, dest, dat, len);
|
||||
}
|
||||
|
||||
Packet::Packet(const char dest[24], const char dat[240]) {
|
||||
Packet::Packet(const char* dest, const char* dat) {
|
||||
uint8_t src[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
getLoRaAddress(src);
|
||||
|
||||
uint8_t destTmp[8];
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
destTmp[i] = (parseByte(dest[3*i]) << 4) | parseByte(dest[3*i + 1]);
|
||||
char str[] = {dest[3*i], dest[3*i + 1]};
|
||||
destTmp[i] = strtoul(str, NULL, 16);
|
||||
}
|
||||
|
||||
init(src, destTmp, dat);
|
||||
}
|
||||
|
||||
Packet::Packet(uint8_t dest[8], const char dat[240]) {
|
||||
Packet::Packet(uint8_t* dest, const char* dat) {
|
||||
uint8_t src[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
getLoRaAddress(src);
|
||||
|
||||
init(src, dest, dat);
|
||||
}
|
||||
|
||||
Packet::Packet(const char src[24], const char dest[24], const char dat[240]) {
|
||||
Packet::Packet(const char* src, const char* dest, const char* dat) {
|
||||
uint8_t srcTmp[8];
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
srcTmp[i] = (parseByte(src[3*i]) << 4) | parseByte(src[3*i + 1]);
|
||||
char str[] = {src[3*i], src[3*i + 1]};
|
||||
srcTmp[i] = strtoul(str, NULL, 16);
|
||||
}
|
||||
|
||||
uint8_t destTmp[8];
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
destTmp[i] = (parseByte(dest[3*i]) << 4) | parseByte(dest[3*i + 1]);
|
||||
char str[] = {dest[3*i], dest[3*i + 1]};
|
||||
destTmp[i] = strtoul(str, NULL, 16);
|
||||
}
|
||||
|
||||
init(srcTmp, destTmp, dat);
|
||||
}
|
||||
|
||||
Packet::Packet(uint8_t src[8], uint8_t dest[8], const char dat[240]) {
|
||||
Packet::Packet(uint8_t* src, uint8_t* dest, const char* dat) {
|
||||
init(src, dest, dat);
|
||||
}
|
||||
|
||||
Packet::Packet(const char dest[24], uint8_t* dat, uint8_t len) {
|
||||
Packet::Packet(const char* dest, uint8_t* dat, uint8_t len) {
|
||||
uint8_t src[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
getLoRaAddress(src);
|
||||
|
||||
uint8_t destTmp[8];
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
destTmp[i] = (parseByte(dest[3*i]) << 4) | parseByte(dest[3*i + 1]);
|
||||
char str[] = {dest[3*i], dest[3*i + 1]};
|
||||
destTmp[i] = strtoul(str, NULL, 16);
|
||||
}
|
||||
|
||||
init(src, destTmp, dat, len);
|
||||
}
|
||||
|
||||
Packet::Packet(uint8_t dest[8], uint8_t* dat, uint8_t len) {
|
||||
Packet::Packet(uint8_t* dest, uint8_t* dat, uint8_t len) {
|
||||
uint8_t src[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
getLoRaAddress(src);
|
||||
|
||||
init(src, dest, dat, len);
|
||||
}
|
||||
|
||||
Packet::Packet(const char src[24], const char dest[24], uint8_t* dat, uint8_t len) {
|
||||
Packet::Packet(const char* src, const char* dest, uint8_t* dat, uint8_t len) {
|
||||
uint8_t srcTmp[8];
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
srcTmp[i] = (parseByte(src[3*i]) << 4) | parseByte(src[3*i + 1]);
|
||||
char str[] = {src[3*i], src[3*i + 1]};
|
||||
srcTmp[i] = strtoul(str, NULL, 16);
|
||||
}
|
||||
|
||||
uint8_t destTmp[8];
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
destTmp[i] = (parseByte(dest[3*i]) << 4) | parseByte(dest[3*i + 1]);
|
||||
char str[] = {dest[3*i], dest[3*i + 1]};
|
||||
destTmp[i] = strtoul(str, NULL, 16);
|
||||
}
|
||||
|
||||
init(srcTmp, destTmp, dat, len);
|
||||
}
|
||||
|
||||
Packet::Packet(uint8_t src[8], uint8_t dest[8], uint8_t* dat, uint8_t len) {
|
||||
Packet::Packet(uint8_t* src, uint8_t* dest, uint8_t* dat, uint8_t len) {
|
||||
init(src, dest, dat, len);
|
||||
}
|
||||
|
||||
void Packet::init(uint8_t src[8], uint8_t dest[8], const char dat[240]) {
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
source[i] = src[i];
|
||||
destination[i] = dest[i];
|
||||
}
|
||||
|
||||
length = 0;
|
||||
for(uint8_t i = 0; i < 240; i++) {
|
||||
data[i] = dat[i];
|
||||
if(data[i] == '\0') {
|
||||
length = i + 16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void Packet::init(uint8_t* src, uint8_t* dest, const char* dat) {
|
||||
init(src, dest, (uint8_t*)dat, strlen(dat));
|
||||
}
|
||||
|
||||
void Packet::init(uint8_t src[8], uint8_t dest[8], uint8_t* dat, uint8_t len) {
|
||||
void Packet::init(uint8_t* src, uint8_t* dest, uint8_t* dat, uint8_t len) {
|
||||
memcpy(source, src, 8);
|
||||
memcpy(destination, dest, 8);
|
||||
length = len + 16;
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
source[i] = src[i];
|
||||
destination[i] = dest[i];
|
||||
}
|
||||
data = new char[len + 1];
|
||||
memcpy(data, dat, len + 1);
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < length; i++) {
|
||||
data[i] = dat[i];
|
||||
String Packet::getSourceStr() {
|
||||
char charArray[24];
|
||||
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
sprintf(charArray + 3*i, "%02X", source[i]);
|
||||
charArray[3*i+2] = ':';
|
||||
}
|
||||
charArray[23] = '\0';
|
||||
|
||||
String str(charArray);
|
||||
return(str);
|
||||
}
|
||||
|
||||
String Packet::getDestinationStr() {
|
||||
char charArray[24];
|
||||
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
sprintf(charArray + 3*i, "%02X", destination[i]);
|
||||
charArray[3*i+2] = ':';
|
||||
}
|
||||
charArray[23] = '\0';
|
||||
|
||||
String str(charArray);
|
||||
return(str);
|
||||
}
|
||||
|
||||
void Packet::setSourceStr(const char* src) {
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
char str[] = {src[3*i], src[3*i + 1]};
|
||||
source[i] = strtoul(str, NULL, 16);
|
||||
}
|
||||
}
|
||||
|
||||
void Packet::getSourceStr(char src[24]) {
|
||||
void Packet::setDestinationStr(const char* dest) {
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
src[3*i] = reparseChar(source[i] >> 4);
|
||||
src[3*i+1] = reparseChar(source[i] & 0x0F);
|
||||
src[3*i+2] = ':';
|
||||
}
|
||||
src[23] = '\0';
|
||||
}
|
||||
|
||||
void Packet::getDestinationStr(char dest[24]) {
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
dest[3*i] = reparseChar(destination[i] >> 4);
|
||||
dest[3*i+1] = reparseChar(destination[i] & 0x0F);
|
||||
dest[3*i+2] = ':';
|
||||
}
|
||||
dest[23] = '\0';
|
||||
}
|
||||
|
||||
void Packet::setSourceStr(const char src[24]) {
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
source[i] = (parseByte(src[3*i]) << 4) | parseByte(src[3*i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
void Packet::setDestinationStr(const char dest[24]) {
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
destination[i] = (parseByte(dest[3*i]) << 4) | parseByte(dest[3*i + 1]);
|
||||
char str[] = {dest[3*i], dest[3*i + 1]};
|
||||
destination[i] = strtoul(str, NULL, 16);
|
||||
}
|
||||
}
|
||||
|
||||
void Packet::copyInto(Packet& pack) {
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
pack.source[i] = source[i];
|
||||
pack.destination[i] = destination[i];
|
||||
}
|
||||
memcpy(pack.source, source, 8);
|
||||
memcpy(pack.destination, destination, 8);
|
||||
strcpy(pack.data, data);
|
||||
}
|
||||
|
||||
void Packet::getLoRaAddress(uint8_t addr[8]) {
|
||||
void Packet::setPacketData(char* charArray) {
|
||||
char* newData = new char[strlen(charArray)];
|
||||
length = strlen(charArray) + 16;
|
||||
strcpy(newData, charArray);
|
||||
delete[] data;
|
||||
data = newData;
|
||||
}
|
||||
|
||||
void Packet::setPacketData(String str) {
|
||||
setPacketData((char*)str.c_str());
|
||||
}
|
||||
|
||||
void Packet::setPacketData(float f, uint8_t decimals) {
|
||||
int i = f;
|
||||
float res = f - i;
|
||||
if (res == 0) {
|
||||
char charArray[16];
|
||||
itoa(i, charArray, 10);
|
||||
setPacketData(charArray);
|
||||
} else {
|
||||
String floatString = String(f, decimals);
|
||||
setPacketData(floatString);
|
||||
}
|
||||
}
|
||||
|
||||
void Packet::getLoRaAddress(uint8_t* addr) {
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
addr[i] = EEPROM.read(i);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Packet::parseByte(char c) {
|
||||
if((c >= 48) && (c <= 57)) {
|
||||
return(c - 48);
|
||||
} else if((c >= 65) && (c <= 70)) {
|
||||
return(c - 55);
|
||||
} else if((c >= 97) && (c <= 102)) {
|
||||
return(c - 87);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
char Packet::reparseChar(uint8_t b) {
|
||||
if(b <= 9) {
|
||||
return(b + 48);
|
||||
} else if((b >= 10) && (b <= 16)) {
|
||||
return(b + 55);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
|
43
src/Packet.h
43
src/Packet.h
|
@ -1,5 +1,5 @@
|
|||
#ifndef _LORALIB_PACKET_H
|
||||
#define _LORALIB_PACKET_H
|
||||
#ifndef _KITELIB_PACKET_H
|
||||
#define _KITELIB_PACKET_H
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
|
@ -12,36 +12,37 @@
|
|||
class Packet {
|
||||
public:
|
||||
Packet(void);
|
||||
Packet(const char dest[24], const char dat[240]);
|
||||
Packet(uint8_t dest[8], const char dat[240]);
|
||||
Packet(const char src[24], const char dest[24], const char dat[240]);
|
||||
Packet(uint8_t src[8], uint8_t dest[8], const char dat[240]);
|
||||
Packet(const char* dest, const char* dat);
|
||||
Packet(uint8_t* dest, const char* dat);
|
||||
Packet(const char* src, const char* dest, const char* dat);
|
||||
Packet(uint8_t* src, uint8_t* dest, const char* dat);
|
||||
|
||||
Packet(const char dest[24], uint8_t* dat, uint8_t len);
|
||||
Packet(uint8_t dest[8], uint8_t* dat, uint8_t len);
|
||||
Packet(const char src[24], const char dest[24], uint8_t* dat, uint8_t len);
|
||||
Packet(uint8_t src[8], uint8_t dest[8], uint8_t* dat, uint8_t len);
|
||||
Packet(const char* dest, uint8_t* dat, uint8_t len);
|
||||
Packet(uint8_t* dest, uint8_t* dat, uint8_t len);
|
||||
Packet(const char* src, const char* dest, uint8_t* dat, uint8_t len);
|
||||
Packet(uint8_t* src, uint8_t* dest, uint8_t* dat, uint8_t len);
|
||||
|
||||
uint8_t source[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint8_t destination[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
char data[240];
|
||||
char* data;
|
||||
uint8_t length = 0;
|
||||
|
||||
void getSourceStr(char src[24]);
|
||||
void getDestinationStr(char dest[24]);
|
||||
String getSourceStr();
|
||||
String getDestinationStr();
|
||||
|
||||
void setSourceStr(const char src[24]);
|
||||
void setDestinationStr(const char dest[24]);
|
||||
void setSourceStr(const char* src);
|
||||
void setDestinationStr(const char* dest);
|
||||
|
||||
void copyInto(Packet& pack);
|
||||
|
||||
private:
|
||||
void init(uint8_t src[8], uint8_t dest[8], const char dat[240]);
|
||||
void init(uint8_t src[8], uint8_t dest[8], uint8_t* dat, uint8_t len);
|
||||
void getLoRaAddress(uint8_t addr[8]);
|
||||
void setPacketData(char* charArray);
|
||||
void setPacketData(String str);
|
||||
void setPacketData(float f, uint8_t decimals = 3);
|
||||
|
||||
uint8_t parseByte(char c);
|
||||
char reparseChar(uint8_t b);
|
||||
private:
|
||||
void init(uint8_t* src, uint8_t* dest, const char* dat);
|
||||
void init(uint8_t* src, uint8_t* dest, uint8_t* dat, uint8_t len);
|
||||
void getLoRaAddress(uint8_t* addr);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
//#define DEBUG
|
||||
//#define KITELIB_DEBUG
|
||||
|
||||
/*#ifdef DEBUG
|
||||
#ifdef KITELIB_DEBUG
|
||||
#define DEBUG_BEGIN(x) Serial.begin (x)
|
||||
#define DEBUG_PRINT(x) Serial.print (x)
|
||||
#define DEBUG_PRINT_DEC(x) Serial.print (x, DEC)
|
||||
|
@ -17,7 +17,7 @@
|
|||
#define DEBUG_PRINTLN(x) Serial.println (x)
|
||||
#define DEBUG_PRINT_STR(x) Serial.print (F(x))
|
||||
#define DEBUG_PRINTLN_STR(x) Serial.println (F(x))
|
||||
#else*/
|
||||
#else
|
||||
#define DEBUG_BEGIN(x)
|
||||
#define DEBUG_PRINT(x)
|
||||
#define DEBUG_PRINT_DEC(x)
|
||||
|
@ -25,58 +25,62 @@
|
|||
#define DEBUG_PRINTLN(x)
|
||||
#define DEBUG_PRINT_STR(x)
|
||||
#define DEBUG_PRINTLN_STR(x)
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
// Shield configuration
|
||||
#define USE_SPI 0x00
|
||||
#define USE_UART 0x01
|
||||
#define USE_I2C 0x02
|
||||
#define INT_NONE 0x00
|
||||
#define INT_0 0x01
|
||||
#define INT_1 0x02
|
||||
#define INT_BOTH 0x03
|
||||
#define USE_SPI 0x00
|
||||
#define USE_UART 0x01
|
||||
#define USE_I2C 0x02
|
||||
#define INT_NONE 0x00
|
||||
#define INT_0 0x01
|
||||
#define INT_1 0x02
|
||||
#define INT_BOTH 0x03
|
||||
|
||||
// UART configuration
|
||||
#define UART_STOPBIT_1 0x01
|
||||
#define UART_STOPBIT_1_5 0x02
|
||||
#define UART_STOPBIT_2 0x03
|
||||
#define UART_PARITY_NONE 0x00
|
||||
#define UART_PARITY_ODD 0x01
|
||||
#define UART_PARITY_EVEN 0x02
|
||||
#define UART_FLOW_NONE 0x00
|
||||
#define UART_FLOW_RTS 0x01
|
||||
#define UART_FLOW_CTS 0x02
|
||||
#define UART_FLOW_BOTH 0x03
|
||||
#define UART_STOPBIT_1 0x01
|
||||
#define UART_STOPBIT_1_5 0x02
|
||||
#define UART_STOPBIT_2 0x03
|
||||
#define UART_PARITY_NONE 0x00
|
||||
#define UART_PARITY_ODD 0x01
|
||||
#define UART_PARITY_EVEN 0x02
|
||||
#define UART_FLOW_NONE 0x00
|
||||
#define UART_FLOW_RTS 0x01
|
||||
#define UART_FLOW_CTS 0x02
|
||||
#define UART_FLOW_BOTH 0x03
|
||||
|
||||
// Common error codes
|
||||
#define ERR_NONE 0x00
|
||||
#define ERR_UNKNOWN 0x63 // maximum error code value is 99, so that it does not interfere with HTTP status codes
|
||||
// Common status codes
|
||||
#define ERR_NONE 0x00
|
||||
#define ERR_UNKNOWN 0x63 // maximum status code value is 99 DEC, so that it does not interfere with HTTP status codes
|
||||
|
||||
// SX1278/SX1272/RF69 error codes
|
||||
#define ERR_CHIP_NOT_FOUND 0x01
|
||||
#define ERR_EEPROM_NOT_INITIALIZED 0x02
|
||||
#define ERR_PACKET_TOO_LONG 0x03
|
||||
#define ERR_TX_TIMEOUT 0x04
|
||||
#define ERR_RX_TIMEOUT 0x05
|
||||
#define ERR_CRC_MISMATCH 0x06
|
||||
#define ERR_INVALID_BANDWIDTH 0x07
|
||||
#define ERR_INVALID_SPREADING_FACTOR 0x08
|
||||
#define ERR_INVALID_CODING_RATE 0x09
|
||||
#define ERR_INVALID_BIT_RANGE 0x10
|
||||
// SX1278/SX1272/RF69 status codes
|
||||
#define ERR_CHIP_NOT_FOUND 0x01
|
||||
#define ERR_EEPROM_NOT_INITIALIZED 0x02
|
||||
#define ERR_PACKET_TOO_LONG 0x03
|
||||
#define ERR_TX_TIMEOUT 0x04
|
||||
#define ERR_RX_TIMEOUT 0x05
|
||||
#define ERR_CRC_MISMATCH 0x06
|
||||
#define ERR_INVALID_BANDWIDTH 0x07
|
||||
#define ERR_INVALID_SPREADING_FACTOR 0x08
|
||||
#define ERR_INVALID_CODING_RATE 0x09
|
||||
#define ERR_INVALID_BIT_RANGE 0x0A
|
||||
#define ERR_INVALID_FREQUENCY 0x0B
|
||||
#define ERR_INVALID_OUTPUT_POWER 0x0C
|
||||
#define PREAMBLE_DETECTED 0x0D
|
||||
#define CHANNEL_FREE 0x0E
|
||||
|
||||
// ESP8266 error codes
|
||||
#define ERR_AT_FAILED 0x01
|
||||
#define ERR_URL_MALFORMED 0x02
|
||||
#define ERR_RESPONSE_MALFORMED_AT 0x03
|
||||
#define ERR_RESPONSE_MALFORMED 0x04
|
||||
#define ERR_MQTT_CONN_VERSION_REJECTED 0x05
|
||||
#define ERR_MQTT_CONN_ID_REJECTED 0x06
|
||||
#define ERR_MQTT_CONN_SERVER_UNAVAILABLE 0x07
|
||||
#define MQTT_CONN_BAD_USERNAME_PASSWORD 0x08
|
||||
#define ERR_MQTT_CONN_NOT_AUTHORIZED 0x09
|
||||
// ESP8266 status codes
|
||||
#define ERR_AT_FAILED 0x01
|
||||
#define ERR_URL_MALFORMED 0x02
|
||||
#define ERR_RESPONSE_MALFORMED_AT 0x03
|
||||
#define ERR_RESPONSE_MALFORMED 0x04
|
||||
#define ERR_MQTT_CONN_VERSION_REJECTED 0x05
|
||||
#define ERR_MQTT_CONN_ID_REJECTED 0x06
|
||||
#define ERR_MQTT_CONN_SERVER_UNAVAILABLE 0x07
|
||||
#define ERR_MQTT_CONN_BAD_USERNAME_PASSWORD 0x08
|
||||
#define ERR_MQTT_CONN_NOT_AUTHORIZED 0x09
|
||||
|
||||
// XBee error codes
|
||||
#define ERR_CMD_MODE_FAILED 0x02
|
||||
// XBee status codes
|
||||
#define ERR_CMD_MODE_FAILED 0x02
|
||||
|
||||
enum Slot {SlotA, SlotB};
|
||||
|
||||
|
|
|
@ -1,262 +1,55 @@
|
|||
#include "SX1272.h"
|
||||
|
||||
SX1272::SX1272(Module* module) {
|
||||
_mod = module;
|
||||
SX1272::SX1272(Module* mod) : SX127x(mod) {
|
||||
|
||||
}
|
||||
|
||||
uint8_t SX1272::begin(Bandwidth bw, SpreadingFactor sf, CodingRate cr, uint16_t addrEeprom) {
|
||||
// copy LoRa modem settings
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
|
||||
// ESP32-only: initialize EEPROM
|
||||
#ifdef ESP32
|
||||
if(!EEPROM.begin(9)) {
|
||||
DEBUG_PRINTLN_STR("Unable to initialize EEPROM");
|
||||
return(ERR_EEPROM_NOT_INITIALIZED);
|
||||
}
|
||||
#endif
|
||||
|
||||
// copy EEPROM start address
|
||||
_addrEeprom = addrEeprom;
|
||||
|
||||
// check if the node has address
|
||||
bool hasAddress = false;
|
||||
for(uint16_t i = 0; i < 8; i++) {
|
||||
if(EEPROM.read(_addrEeprom + i) != 255) {
|
||||
hasAddress = true;
|
||||
break;
|
||||
}
|
||||
uint8_t SX1272::begin(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t addrEeprom) {
|
||||
uint8_t state = SX127x::begin(freq, bw, sf, cr, syncWord, addrEeprom);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// generate new address
|
||||
if(!hasAddress) {
|
||||
randomSeed(analogRead(5));
|
||||
generateLoRaAdress();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.print("LoRa node address string: ");
|
||||
#endif
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
_address[i] = EEPROM.read(i);
|
||||
#ifdef DEBUG
|
||||
Serial.print(_address[i], HEX);
|
||||
if(i < 7) {
|
||||
Serial.print(":");
|
||||
} else {
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// set module properties
|
||||
_mod->init(USE_SPI, INT_BOTH);
|
||||
|
||||
// try to find the SX1272 chip
|
||||
uint8_t i = 0;
|
||||
bool flagFound = false;
|
||||
while((i < 10) && !flagFound) {
|
||||
uint8_t version = _mod->SPIreadRegister(SX1272_REG_VERSION);
|
||||
if(version == 0x22) {
|
||||
flagFound = true;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
Serial.print("SX1272 not found! (");
|
||||
Serial.print(i + 1);
|
||||
Serial.print(" of 10 tries) SX1272_REG_VERSION == ");
|
||||
|
||||
char buffHex[5];
|
||||
sprintf(buffHex, "0x%02X", version);
|
||||
Serial.print(buffHex);
|
||||
Serial.println();
|
||||
#endif
|
||||
delay(1000);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flagFound) {
|
||||
DEBUG_PRINTLN_STR("No SX1272 found!");
|
||||
SPI.end();
|
||||
return(ERR_CHIP_NOT_FOUND);
|
||||
} else {
|
||||
DEBUG_PRINTLN_STR("Found SX1272! (match by SX1272_REG_VERSION == 0x12)");
|
||||
}
|
||||
|
||||
// configure LoRa modem
|
||||
return(config(_bw, _sf, _cr));
|
||||
return(config(freq, bw, sf, cr, syncWord));
|
||||
}
|
||||
|
||||
uint8_t SX1272::transmit(Packet& pack) {
|
||||
char buffer[256];
|
||||
|
||||
// copy packet source and destination addresses into buffer
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
buffer[i] = pack.source[i];
|
||||
buffer[i+8] = pack.destination[i];
|
||||
}
|
||||
|
||||
// copy packet data into buffer
|
||||
for(uint8_t i = 0; i < pack.length; i++) {
|
||||
buffer[i+16] = pack.data[i];
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
setMode(SX1272_STANDBY);
|
||||
|
||||
// set DIO pin mapping
|
||||
_mod->SPIsetRegValue(SX1272_REG_DIO_MAPPING_1, SX1272_DIO0_TX_DONE, 7, 6);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
// check overall packet length
|
||||
if(pack.length > 256) {
|
||||
return(ERR_PACKET_TOO_LONG);
|
||||
}
|
||||
|
||||
// write packet to FIFO
|
||||
_mod->SPIsetRegValue(SX1272_REG_PAYLOAD_LENGTH, pack.length);
|
||||
_mod->SPIsetRegValue(SX1272_REG_FIFO_TX_BASE_ADDR, SX1272_FIFO_TX_BASE_ADDR_MAX);
|
||||
_mod->SPIsetRegValue(SX1272_REG_FIFO_ADDR_PTR, SX1272_FIFO_TX_BASE_ADDR_MAX);
|
||||
_mod->SPIwriteRegisterBurstStr(SX1272_REG_FIFO, buffer, pack.length);
|
||||
|
||||
|
||||
// set mode to transmit
|
||||
setMode(SX1272_TX);
|
||||
|
||||
// wait for transmission end
|
||||
unsigned long start = millis();
|
||||
while(!_mod->getInt0State()) {
|
||||
DEBUG_PRINT('.');
|
||||
}
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX1272::receive(Packet& pack) {
|
||||
char buffer[256];
|
||||
uint32_t startTime = millis();
|
||||
|
||||
// set mode to standby
|
||||
setMode(SX1272_STANDBY);
|
||||
|
||||
// set DIO pin mapping
|
||||
_mod->SPIsetRegValue(SX1272_REG_DIO_MAPPING_1, SX1272_DIO0_RX_DONE | SX1272_DIO1_RX_TIMEOUT, 7, 4);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
// set FIFO address pointers
|
||||
_mod->SPIsetRegValue(SX1272_REG_FIFO_RX_BASE_ADDR, SX1272_FIFO_RX_BASE_ADDR_MAX);
|
||||
_mod->SPIsetRegValue(SX1272_REG_FIFO_ADDR_PTR, SX1272_FIFO_RX_BASE_ADDR_MAX);
|
||||
|
||||
// set mode to receive
|
||||
setMode(SX1272_RXSINGLE);
|
||||
|
||||
// wait for packet reception or timeout
|
||||
while(!_mod->getInt0State()) {
|
||||
if(_mod->getInt1State()) {
|
||||
clearIRQFlags();
|
||||
return(ERR_RX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
// check received packet CRC
|
||||
if(_mod->SPIgetRegValue(SX1272_REG_IRQ_FLAGS, 5, 5) == SX1272_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR) {
|
||||
return(ERR_CRC_MISMATCH);
|
||||
}
|
||||
|
||||
// get header type
|
||||
uint8_t headerMode = _mod->SPIgetRegValue(SX1272_REG_MODEM_CONFIG_1, 0, 0);
|
||||
if(headerMode == SX1272_HEADER_EXPL_MODE) {
|
||||
pack.length = _mod->SPIgetRegValue(SX1272_REG_RX_NB_BYTES);
|
||||
}
|
||||
|
||||
// read packet from FIFO
|
||||
_mod->SPIreadRegisterBurstStr(SX1272_REG_FIFO, pack.length, buffer);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
// get packet source and destination addresses from buffer
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
pack.source[i] = buffer[i];
|
||||
pack.destination[i] = buffer[i+8];
|
||||
}
|
||||
|
||||
// get packet source and destination addresses from buffer
|
||||
for(uint8_t i = 16; i < pack.length; i++) {
|
||||
pack.data[i-16] = buffer[i];
|
||||
}
|
||||
pack.data[pack.length-16] = 0;
|
||||
|
||||
// measure overall datarate
|
||||
uint32_t elapsedTime = millis() - startTime;
|
||||
dataRate = (pack.length*8.0)/((float)elapsedTime/1000.0);
|
||||
|
||||
// get packet RSSI
|
||||
lastPacketRSSI = getLastPacketRSSI();
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX1272::sleep() {
|
||||
return(setMode(0b00000000));
|
||||
}
|
||||
|
||||
uint8_t SX1272::standby() {
|
||||
return(setMode(0b00000001));
|
||||
}
|
||||
|
||||
uint8_t SX1272::setBandwidth(Bandwidth bw) {
|
||||
uint8_t state = config(bw, _sf, _cr);
|
||||
uint8_t SX1272::setBandwidth(uint32_t bw) {
|
||||
uint8_t state = SX1272::config(bw, _sf, _cr, _freq, _syncWord);
|
||||
if(state == ERR_NONE) {
|
||||
_bw = bw;
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
uint8_t SX1272::setSpreadingFactor(SpreadingFactor sf) {
|
||||
uint8_t state = config(_bw, sf, _cr);
|
||||
uint8_t SX1272::setSpreadingFactor(uint8_t sf) {
|
||||
uint8_t state = SX1272::config(_bw, sf, _cr, _freq, _syncWord);
|
||||
if(state == ERR_NONE) {
|
||||
_sf = sf;
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
uint8_t SX1272::setCodingRate(CodingRate cr) {
|
||||
uint8_t state = config(_bw, _sf, cr);
|
||||
uint8_t SX1272::setCodingRate(uint8_t cr) {
|
||||
uint8_t state = SX1272::config(_bw, _sf, cr, _freq, _syncWord);
|
||||
if(state == ERR_NONE) {
|
||||
_cr = cr;
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
void SX1272::generateLoRaAdress() {
|
||||
for(uint8_t i = _addrEeprom; i < (_addrEeprom + 8); i++) {
|
||||
EEPROM.write(i, (uint8_t)random(0, 256));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t SX1272::config(Bandwidth bw, SpreadingFactor sf, CodingRate cr) {
|
||||
uint8_t SX1272::config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord) {
|
||||
uint8_t status = ERR_NONE;
|
||||
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
|
||||
|
||||
//check the supplied bw, cr and sf values
|
||||
// check the supplied BW, CR and SF values
|
||||
switch(bw) {
|
||||
case BW_125_00_KHZ:
|
||||
case 125000:
|
||||
newBandwidth = SX1272_BW_125_00_KHZ;
|
||||
break;
|
||||
case BW_250_00_KHZ:
|
||||
case 250000:
|
||||
newBandwidth = SX1272_BW_250_00_KHZ;
|
||||
break;
|
||||
case BW_500_00_KHZ:
|
||||
case 500000:
|
||||
newBandwidth = SX1272_BW_500_00_KHZ;
|
||||
break;
|
||||
default:
|
||||
|
@ -264,130 +57,107 @@ uint8_t SX1272::config(Bandwidth bw, SpreadingFactor sf, CodingRate cr) {
|
|||
}
|
||||
|
||||
switch(sf) {
|
||||
case SF_6:
|
||||
newSpreadingFactor = SX1272_SF_6;
|
||||
case 6:
|
||||
newSpreadingFactor = SX127X_SF_6;
|
||||
break;
|
||||
case SF_7:
|
||||
newSpreadingFactor = SX1272_SF_7;
|
||||
case 7:
|
||||
newSpreadingFactor = SX127X_SF_7;
|
||||
break;
|
||||
case SF_8:
|
||||
newSpreadingFactor = SX1272_SF_8;
|
||||
case 8:
|
||||
newSpreadingFactor = SX127X_SF_8;
|
||||
break;
|
||||
case SF_9:
|
||||
newSpreadingFactor = SX1272_SF_9;
|
||||
case 9:
|
||||
newSpreadingFactor = SX127X_SF_9;
|
||||
break;
|
||||
case SF_10:
|
||||
newSpreadingFactor = SX1272_SF_10;
|
||||
case 10:
|
||||
newSpreadingFactor = SX127X_SF_10;
|
||||
break;
|
||||
case SF_11:
|
||||
newSpreadingFactor = SX1272_SF_11;
|
||||
case 11:
|
||||
newSpreadingFactor = SX127X_SF_11;
|
||||
break;
|
||||
case SF_12:
|
||||
newSpreadingFactor = SX1272_SF_12;
|
||||
case 12:
|
||||
newSpreadingFactor = SX127X_SF_12;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_SPREADING_FACTOR);
|
||||
}
|
||||
|
||||
switch(cr) {
|
||||
case CR_4_5:
|
||||
case 5:
|
||||
newCodingRate = SX1272_CR_4_5;
|
||||
break;
|
||||
case CR_4_6:
|
||||
case 6:
|
||||
newCodingRate = SX1272_CR_4_6;
|
||||
break;
|
||||
case CR_4_7:
|
||||
case 7:
|
||||
newCodingRate = SX1272_CR_4_7;
|
||||
break;
|
||||
case CR_4_8:
|
||||
case 8:
|
||||
newCodingRate = SX1272_CR_4_8;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_CODING_RATE);
|
||||
}
|
||||
|
||||
// set mode to SLEEP
|
||||
status = setMode(SX1272_SLEEP);
|
||||
if((freq < 137.0) || (freq > 525.0)) {
|
||||
return(ERR_INVALID_FREQUENCY);
|
||||
}
|
||||
|
||||
// execute common part
|
||||
status = SX1272::configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// set LoRa mode
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_OP_MODE, SX1272_LORA, 7, 7);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
// configuration successful, save the new settings
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
_freq = freq;
|
||||
|
||||
// set carrier frequency
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_FRF_MSB, SX1272_FRF_MSB);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_FRF_MID, SX1272_FRF_MID);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_FRF_LSB, SX1272_FRF_LSB);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX1272::configCommon(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
|
||||
// configure common registers
|
||||
uint8_t status = SX127x::config(bw, sf, cr, freq, syncWord);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// output power configuration
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_PA_CONFIG, SX1272_PA_SELECT_BOOST | SX1272_OUTPUT_POWER);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_OCP, SX1272_OCP_ON | SX1272_OCP_TRIM, 5, 0);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_LNA, SX1272_LNA_GAIN_1 | SX1272_LNA_BOOST_ON);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX1272_PA_BOOST_ON, 2, 0);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// turn off frequency hopping
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_HOP_PERIOD, SX1272_HOP_PERIOD_OFF);
|
||||
// enable LNA gain setting by register
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1272_AGC_AUTO_OFF, 2, 2);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// basic setting (bw, cr, sf, header mode and CRC)
|
||||
if(newSpreadingFactor == SX1272_SF_6) {
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_MODEM_CONFIG_2, SX1272_SF_6 | SX1272_TX_MODE_SINGLE | SX1272_RX_CRC_MODE_OFF, 7, 2);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_MODEM_CONFIG_1, newBandwidth | newCodingRate | SX1272_HEADER_IMPL_MODE);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_DETECT_OPTIMIZE, SX1272_DETECT_OPTIMIZE_SF_6, 2, 0);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_DETECTION_THRESHOLD, SX1272_DETECTION_THRESHOLD_SF_6);
|
||||
// set SF6 optimizations
|
||||
if(sf == SX127X_SF_6) {
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, bw | cr | SX1272_HEADER_IMPL_MODE | SX1272_RX_CRC_MODE_OFF, 7, 1);
|
||||
} else {
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_MODEM_CONFIG_2, newSpreadingFactor | SX1272_TX_MODE_SINGLE | SX1272_RX_CRC_MODE_ON, 7, 2);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_MODEM_CONFIG_1, newBandwidth | newCodingRate | SX1272_HEADER_EXPL_MODE);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_DETECT_OPTIMIZE, SX1272_DETECT_OPTIMIZE_SF_7_12, 2, 0);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_DETECTION_THRESHOLD, SX1272_DETECTION_THRESHOLD_SF_7_12);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, bw | cr | SX1272_HEADER_EXPL_MODE | SX1272_RX_CRC_MODE_ON, 7, 1);
|
||||
}
|
||||
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// set default preamble length
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_PREAMBLE_MSB, SX1272_PREAMBLE_LENGTH_MSB);
|
||||
status = _mod->SPIsetRegValue(SX1272_REG_PREAMBLE_LSB, SX1272_PREAMBLE_LENGTH_LSB);
|
||||
// calculate symbol length and set low datarate optimization, if needed
|
||||
uint16_t base = 1;
|
||||
float symbolLength = (float)(base << _sf) / (float)_bw;
|
||||
if(symbolLength >= 0.016) {
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_ON, 0, 0);
|
||||
} else {
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0);
|
||||
}
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// set mode to STANDBY
|
||||
status = setMode(SX1272_STANDBY);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// save the new settings
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX1272::setMode(uint8_t mode) {
|
||||
_mod->SPIsetRegValue(SX1272_REG_OP_MODE, mode, 2, 0);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void SX1272::clearIRQFlags() {
|
||||
_mod->SPIwriteRegister(SX1272_REG_IRQ_FLAGS, 0b11111111);
|
||||
}
|
||||
|
||||
int8_t SX1272::getLastPacketRSSI() {
|
||||
return(-164 + _mod->SPIgetRegValue(SX1272_REG_PKT_RSSI_VALUE));
|
||||
return(status);
|
||||
}
|
||||
|
|
|
@ -1,58 +1,11 @@
|
|||
#ifndef _KITELIB_SX1272_H
|
||||
#define _KITELIB_SX1272_H
|
||||
|
||||
#include <EEPROM.h>
|
||||
|
||||
#include "TypeDef.h"
|
||||
#include "Module.h"
|
||||
#include "Packet.h"
|
||||
#include "SX127x.h"
|
||||
|
||||
//SX1272 register map
|
||||
#define SX1272_REG_FIFO 0x00
|
||||
#define SX1272_REG_OP_MODE 0x01
|
||||
#define SX1272_REG_FRF_MSB 0x06
|
||||
#define SX1272_REG_FRF_MID 0x07
|
||||
#define SX1272_REG_FRF_LSB 0x08
|
||||
#define SX1272_REG_PA_CONFIG 0x09
|
||||
#define SX1272_REG_PA_RAMP 0x0A
|
||||
#define SX1272_REG_OCP 0x0B
|
||||
#define SX1272_REG_LNA 0x0C
|
||||
#define SX1272_REG_FIFO_ADDR_PTR 0x0D
|
||||
#define SX1272_REG_FIFO_TX_BASE_ADDR 0x0E
|
||||
#define SX1272_REG_FIFO_RX_BASE_ADDR 0x0F
|
||||
#define SX1272_REG_FIFO_RX_CURRENT_ADDR 0x10
|
||||
#define SX1272_REG_IRQ_FLAGS_MASK 0x11
|
||||
#define SX1272_REG_IRQ_FLAGS 0x12
|
||||
#define SX1272_REG_RX_NB_BYTES 0x13
|
||||
#define SX1272_REG_RX_HEADER_CNT_VALUE_MSB 0x14
|
||||
#define SX1272_REG_RX_HEADER_CNT_VALUE_LSB 0x15
|
||||
#define SX1272_REG_RX_PACKET_CNT_VALUE_MSB 0x16
|
||||
#define SX1272_REG_RX_PACKET_CNT_VALUE_LSB 0x17
|
||||
#define SX1272_REG_MODEM_STAT 0x18
|
||||
#define SX1272_REG_PKT_SNR_VALUE 0x19
|
||||
#define SX1272_REG_PKT_RSSI_VALUE 0x1A
|
||||
#define SX1272_REG_RSSI_VALUE 0x1B
|
||||
#define SX1272_REG_HOP_CHANNEL 0x1C
|
||||
#define SX1272_REG_MODEM_CONFIG_1 0x1D
|
||||
#define SX1272_REG_MODEM_CONFIG_2 0x1E
|
||||
#define SX1272_REG_SYMB_TIMEOUT_LSB 0x1F
|
||||
#define SX1272_REG_PREAMBLE_MSB 0x20
|
||||
#define SX1272_REG_PREAMBLE_LSB 0x21
|
||||
#define SX1272_REG_PAYLOAD_LENGTH 0x22
|
||||
#define SX1272_REG_MAX_PAYLOAD_LENGTH 0x23
|
||||
#define SX1272_REG_HOP_PERIOD 0x24
|
||||
#define SX1272_REG_FIFO_RX_BYTE_ADDR 0x25
|
||||
#define SX1272_REG_FEI_MSB 0x28
|
||||
#define SX1272_REG_FEI_MID 0x29
|
||||
#define SX1272_REG_FEI_LSB 0x2A
|
||||
#define SX1272_REG_RSSI_WIDEBAND 0x2C
|
||||
#define SX1272_REG_DETECT_OPTIMIZE 0x31
|
||||
#define SX1272_REG_INVERT_IQ 0x33
|
||||
#define SX1272_REG_DETECTION_THRESHOLD 0x37
|
||||
#define SX1272_REG_SYNC_WORD 0x39
|
||||
#define SX1272_REG_DIO_MAPPING_1 0x40
|
||||
#define SX1272_REG_DIO_MAPPING_2 0x41
|
||||
#define SX1272_REG_VERSION 0x42
|
||||
//SX1272 specific register map
|
||||
#define SX1272_REG_AGC_REF 0x43
|
||||
#define SX1272_REG_AGC_THRESH_1 0x44
|
||||
#define SX1272_REG_AGC_THRESH_2 0x45
|
||||
|
@ -66,47 +19,11 @@
|
|||
#define SX1272_REG_BIT_RATE_FRAC 0x70
|
||||
|
||||
//SX1272 LoRa modem settings
|
||||
//SX1272_REG_OP_MODE MSB LSB DESCRIPTION
|
||||
#define SX1272_FSK_OOK 0b00000000 // 7 7 FSK/OOK mode
|
||||
#define SX1272_LORA 0b10000000 // 7 7 LoRa mode
|
||||
#define SX1272_ACCESS_SHARED_REG_OFF 0b00000000 // 6 6 access LoRa registers (0x0D:0x3F) in LoRa mode
|
||||
#define SX1272_ACCESS_SHARED_REG_ON 0b01000000 // 6 6 access FSK registers (0x0D:0x3F) in LoRa mode
|
||||
#define SX1272_SLEEP 0b00000000 // 2 0 sleep
|
||||
#define SX1272_STANDBY 0b00000001 // 2 0 standby
|
||||
#define SX1272_FSTX 0b00000010 // 2 0 frequency synthesis TX
|
||||
#define SX1272_TX 0b00000011 // 2 0 transmit
|
||||
#define SX1272_FSRX 0b00000100 // 2 0 frequency synthesis RX
|
||||
#define SX1272_RXCONTINUOUS 0b00000101 // 2 0 receive continuous
|
||||
#define SX1272_RXSINGLE 0b00000110 // 2 0 receive single
|
||||
#define SX1272_CAD 0b00000111 // 2 0 channel activity detection
|
||||
|
||||
//SX1272_REG_FRF_MSB + REG_FRF_MID + REG_FRF_LSB
|
||||
#define SX1272_FRF_MSB 0xE4 // 7 0 carrier frequency setting: f_RF = (F(XOSC) * FRF)/2^19
|
||||
#define SX1272_FRF_MID 0xC0 // 7 0 where F(XOSC) = 32 MHz
|
||||
#define SX1272_FRF_LSB 0x00 // 7 0 FRF = 3 byte value of FRF registers
|
||||
|
||||
//SX1272_REG_PA_CONFIG
|
||||
#define SX1272_PA_SELECT_RFO 0b00000000 // 7 7 RFIO pin output, power limited to +13 dBm
|
||||
#define SX1272_PA_SELECT_BOOST 0b10000000 // 7 7 PA_BOOST pin output, power limited to +20 dBm
|
||||
#define SX1272_OUTPUT_POWER 0b00001111 // 3 0 output power: P_out = -1 + OUTPUT_POWER [dBm] for PA_SELECT_BOOST
|
||||
|
||||
//SX1272_REG_OCP
|
||||
#define SX1272_OCP_OFF 0b00000000 // 5 5 PA overload current protection disabled
|
||||
#define SX1272_OCP_ON 0b00100000 // 5 5 PA overload current protection enabled
|
||||
#define SX1272_OCP_TRIM 0b00001011 // 4 0 OCP current: I_max(OCP_TRIM = 0b1011) = 100 mA
|
||||
|
||||
//SX1272_REG_LNA
|
||||
#define SX1272_LNA_GAIN_0 0b00000000 // 7 5 LNA gain setting: not used
|
||||
#define SX1272_LNA_GAIN_1 0b00100000 // 7 5 max gain
|
||||
#define SX1272_LNA_GAIN_2 0b01000000 // 7 5 .
|
||||
#define SX1272_LNA_GAIN_3 0b01100000 // 7 5 .
|
||||
#define SX1272_LNA_GAIN_4 0b10000000 // 7 5 .
|
||||
#define SX1272_LNA_GAIN_5 0b10100000 // 7 5 .
|
||||
#define SX1272_LNA_GAIN_6 0b11000000 // 7 5 min gain
|
||||
#define SX1272_LNA_GAIN_7 0b11100000 // 7 5 not used
|
||||
#define SX1272_LNA_BOOST_OFF 0b00000000 // 1 0 default LNA current
|
||||
#define SX1272_LNA_BOOST_ON 0b00000011 // 1 0 150% LNA current
|
||||
|
||||
//SX1272_REG_MODEM_CONFIG_1
|
||||
#define SX1272_BW_125_00_KHZ 0b00000000 // 7 6 bandwidth: 125 kHz
|
||||
#define SX1272_BW_250_00_KHZ 0b01000000 // 7 6 250 kHz
|
||||
|
@ -123,109 +40,25 @@
|
|||
#define SX1272_LOW_DATA_RATE_OPT_ON 0b00000001 // 0 0 low data rate optimization enabled, mandatory for SF 11 and 12 with BW 125 kHz
|
||||
|
||||
//SX1272_REG_MODEM_CONFIG_2
|
||||
#define SX1272_SF_6 0b01100000 // 7 4 spreading factor: 64 chips/bit
|
||||
#define SX1272_SF_7 0b01110000 // 7 4 128 chips/bit
|
||||
#define SX1272_SF_8 0b10000000 // 7 4 256 chips/bit
|
||||
#define SX1272_SF_9 0b10010000 // 7 4 512 chips/bit
|
||||
#define SX1272_SF_10 0b10100000 // 7 4 1024 chips/bit
|
||||
#define SX1272_SF_11 0b10110000 // 7 4 2048 chips/bit
|
||||
#define SX1272_SF_12 0b11000000 // 7 4 4096 chips/bit
|
||||
#define SX1272_TX_MODE_SINGLE 0b00000000 // 3 3 single TX
|
||||
#define SX1272_TX_MODE_CONT 0b00001000 // 3 3 continuous TX
|
||||
#define SX1272_AGC_AUTO_OFF 0b00000000 // 2 2 LNA gain set by REG_LNA
|
||||
#define SX1272_AGC_AUTO_ON 0b00000100 // 2 2 LNA gain set by internal AGC loop
|
||||
#define SX1272_RX_TIMEOUT_MSB 0b00000000 // 1 0
|
||||
|
||||
//SX1272_REG_SYMB_TIMEOUT_LSB
|
||||
#define SX1272_RX_TIMEOUT_LSB 0b01100100 // 7 0 10 bit RX operation timeout
|
||||
|
||||
//SX1272_REG_PREAMBLE_MSB + REG_PREAMBLE_LSB
|
||||
#define SX1272_PREAMBLE_LENGTH_MSB 0b00000000 // 7 0 2 byte preamble length setting: l_P = PREAMBLE_LENGTH + 4.25
|
||||
#define SX1272_PREAMBLE_LENGTH_LSB 0b00001000 // 7 0 where l_p = preamble length
|
||||
|
||||
//SX1272_REG_DETECT_OPTIMIZE
|
||||
#define SX1272_DETECT_OPTIMIZE_SF_6 0b00000101 // 2 0 SF6 detection optimization
|
||||
#define SX1272_DETECT_OPTIMIZE_SF_7_12 0b00000011 // 2 0 SF7 to SF12 detection optimization
|
||||
|
||||
//SX1272_REG_DETECTION_THRESHOLD
|
||||
#define SX1272_DETECTION_THRESHOLD_SF_6 0b00001100 // 7 0 SF6 detection threshold
|
||||
#define SX1272_DETECTION_THRESHOLD_SF_7_12 0b00001010 // 7 0 SF7 to SF12 detection threshold
|
||||
|
||||
//SX1272_REG_PA_DAC
|
||||
#define SX1272_PA_BOOST_OFF 0b00000100 // 2 0 PA_BOOST disabled
|
||||
#define SX1272_PA_BOOST_ON 0b00000111 // 2 0 +20 dBm on PA_BOOST when OUTPUT_POWER = 0b1111
|
||||
|
||||
//SX1272_REG_HOP_PERIOD
|
||||
#define SX1272_HOP_PERIOD_OFF 0b00000000 // 7 0 number of periods between frequency hops; 0 = disabled
|
||||
#define SX1272_HOP_PERIOD_MAX 0b11111111 // 7 0
|
||||
|
||||
//SX1272_REG_DIO_MAPPING_1
|
||||
#define SX1272_DIO0_RX_DONE 0b00000000 // 7 6
|
||||
#define SX1272_DIO0_TX_DONE 0b01000000 // 7 6
|
||||
#define SX1272_DIO0_CAD_DONE 0b10000000 // 7 6
|
||||
#define SX1272_DIO1_RX_TIMEOUT 0b00000000 // 5 4
|
||||
#define SX1272_DIO1_FHSS_CHANGE_CHANNEL 0b00010000 // 5 4
|
||||
#define SX1272_DIO1_CAD_DETECTED 0b00100000 // 5 4
|
||||
|
||||
//SX1272_REG_IRQ_FLAGS
|
||||
#define SX1272_CLEAR_IRQ_FLAG_RX_TIMEOUT 0b10000000 // 7 7 timeout
|
||||
#define SX1272_CLEAR_IRQ_FLAG_RX_DONE 0b01000000 // 6 6 packet reception complete
|
||||
#define SX1272_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR 0b00100000 // 5 5 payload CRC error
|
||||
#define SX1272_CLEAR_IRQ_FLAG_VALID_HEADER 0b00010000 // 4 4 valid header received
|
||||
#define SX1272_CLEAR_IRQ_FLAG_TX_DONE 0b00001000 // 3 3 payload transmission complete
|
||||
#define SX1272_CLEAR_IRQ_FLAG_CAD_DONE 0b00000100 // 2 2 CAD complete
|
||||
#define SX1272_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL 0b00000010 // 1 1 FHSS change channel
|
||||
#define SX1272_CLEAR_IRQ_FLAG_CAD_DETECTED 0b00000001 // 0 0 valid LoRa signal detected during CAD operation
|
||||
|
||||
//SX1272_REG_IRQ_FLAGS_MASK
|
||||
#define SX1272_MASK_IRQ_FLAG_RX_TIMEOUT 0b01111111 // 7 7 timeout
|
||||
#define SX1272_MASK_IRQ_FLAG_RX_DONE 0b10111111 // 6 6 packet reception complete
|
||||
#define SX1272_MASK_IRQ_FLAG_PAYLOAD_CRC_ERROR 0b11011111 // 5 5 payload CRC error
|
||||
#define SX1272_MASK_IRQ_FLAG_VALID_HEADER 0b11101111 // 4 4 valid header received
|
||||
#define SX1272_MASK_IRQ_FLAG_TX_DONE 0b11110111 // 3 3 payload transmission complete
|
||||
#define SX1272_MASK_IRQ_FLAG_CAD_DONE 0b11111011 // 2 2 CAD complete
|
||||
#define SX1272_MASK_IRQ_FLAG_FHSS_CHANGE_CHANNEL 0b11111101 // 1 1 FHSS change channel
|
||||
#define SX1272_MASK_IRQ_FLAG_CAD_DETECTED 0b11111110 // 0 0 valid LoRa signal detected during CAD operation
|
||||
|
||||
//SX1272_REG_FIFO_TX_BASE_ADDR
|
||||
#define SX1272_FIFO_TX_BASE_ADDR_MAX 0b00000000 // 7 0 allocate the entire FIFO buffer for TX only
|
||||
|
||||
//SX1272_REG_FIFO_RX_BASE_ADDR
|
||||
#define SX1272_FIFO_RX_BASE_ADDR_MAX 0b00000000 // 7 0 allocate the entire FIFO buffer for RX only
|
||||
|
||||
class SX1272 {
|
||||
class SX1272: public SX127x {
|
||||
public:
|
||||
SX1272(Module* module);
|
||||
SX1272(Module* mod);
|
||||
|
||||
float dataRate;
|
||||
int8_t lastPacketRSSI;
|
||||
uint8_t begin(float freq = 434.0, uint32_t bw = 125000, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = SX127X_SYNC_WORD, uint16_t addrEeprom = 0);
|
||||
|
||||
uint8_t begin(Bandwidth bw = BW_125_00_KHZ, SpreadingFactor sf = SF_9, CodingRate cr = CR_4_7, uint16_t addrEeprom = 0);
|
||||
uint8_t transmit(Packet& pack);
|
||||
uint8_t receive(Packet& pack);
|
||||
|
||||
uint8_t sleep();
|
||||
uint8_t standby();
|
||||
|
||||
uint8_t setBandwidth(Bandwidth bw);
|
||||
uint8_t setSpreadingFactor(SpreadingFactor sf);
|
||||
uint8_t setCodingRate(CodingRate cr);
|
||||
uint8_t setBandwidth(uint32_t bw);
|
||||
uint8_t setSpreadingFactor(uint8_t sf);
|
||||
uint8_t setCodingRate(uint8_t cr);
|
||||
|
||||
protected:
|
||||
uint8_t configCommon(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord); // common for SX1272/73
|
||||
|
||||
private:
|
||||
Module* _mod;
|
||||
uint8_t config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord); // specific to SX1272
|
||||
|
||||
Bandwidth _bw;
|
||||
SpreadingFactor _sf;
|
||||
CodingRate _cr;
|
||||
|
||||
uint8_t _address[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint16_t _addrEeprom;
|
||||
|
||||
void generateLoRaAdress();
|
||||
uint8_t config(Bandwidth bw, SpreadingFactor sf, CodingRate cr);
|
||||
uint8_t setMode(uint8_t mode);
|
||||
void clearIRQFlags();
|
||||
int8_t getLastPacketRSSI();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
76
src/modules/SX1273.cpp
Normal file
76
src/modules/SX1273.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include "SX1273.h"
|
||||
|
||||
SX1273::SX1273(Module* mod) : SX1272(mod) {
|
||||
|
||||
}
|
||||
|
||||
uint8_t SX1273::config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
|
||||
uint8_t status = ERR_NONE;
|
||||
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
|
||||
|
||||
// check the supplied BW, CR and SF values
|
||||
switch(bw) {
|
||||
case 125000:
|
||||
newBandwidth = SX1272_BW_125_00_KHZ;
|
||||
break;
|
||||
case 250000:
|
||||
newBandwidth = SX1272_BW_250_00_KHZ;
|
||||
break;
|
||||
case 500000:
|
||||
newBandwidth = SX1272_BW_500_00_KHZ;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_BANDWIDTH);
|
||||
}
|
||||
|
||||
switch(sf) {
|
||||
case 6:
|
||||
newSpreadingFactor = SX127X_SF_6;
|
||||
break;
|
||||
case 7:
|
||||
newSpreadingFactor = SX127X_SF_7;
|
||||
break;
|
||||
case 8:
|
||||
newSpreadingFactor = SX127X_SF_8;
|
||||
break;
|
||||
case 9:
|
||||
newSpreadingFactor = SX127X_SF_9;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_SPREADING_FACTOR);
|
||||
}
|
||||
|
||||
switch(cr) {
|
||||
case 5:
|
||||
newCodingRate = SX1272_CR_4_5;
|
||||
break;
|
||||
case 6:
|
||||
newCodingRate = SX1272_CR_4_6;
|
||||
break;
|
||||
case 7:
|
||||
newCodingRate = SX1272_CR_4_7;
|
||||
break;
|
||||
case 8:
|
||||
newCodingRate = SX1272_CR_4_8;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_CODING_RATE);
|
||||
}
|
||||
|
||||
if((freq < 860.0) || (freq > 1020.0)) {
|
||||
return(ERR_INVALID_FREQUENCY);
|
||||
}
|
||||
|
||||
// execute common part
|
||||
status = configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// configuration successful, save the new settings
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
15
src/modules/SX1273.h
Normal file
15
src/modules/SX1273.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef _KITELIB_SX1273_H
|
||||
#define _KITELIB_SX1273_H
|
||||
|
||||
#include "TypeDef.h"
|
||||
#include "SX1272.h"
|
||||
|
||||
class SX1273: public SX1272 {
|
||||
public:
|
||||
SX1273(Module* mod);
|
||||
|
||||
private:
|
||||
uint8_t config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord);
|
||||
};
|
||||
|
||||
#endif
|
85
src/modules/SX1276.cpp
Normal file
85
src/modules/SX1276.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include "SX1276.h"
|
||||
|
||||
SX1276::SX1276(Module* mod) : SX1278(mod) {
|
||||
|
||||
}
|
||||
|
||||
uint8_t SX1276::config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
|
||||
uint8_t status = ERR_NONE;
|
||||
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
|
||||
|
||||
// check the supplied BW, CR and SF values
|
||||
switch(bw) {
|
||||
case 125000:
|
||||
newBandwidth = SX1278_BW_125_00_KHZ;
|
||||
break;
|
||||
case 250000:
|
||||
newBandwidth = SX1278_BW_250_00_KHZ;
|
||||
break;
|
||||
case 500000:
|
||||
newBandwidth = SX1278_BW_500_00_KHZ;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_BANDWIDTH);
|
||||
}
|
||||
|
||||
switch(sf) {
|
||||
case 6:
|
||||
newSpreadingFactor = SX127X_SF_6;
|
||||
break;
|
||||
case 7:
|
||||
newSpreadingFactor = SX127X_SF_7;
|
||||
break;
|
||||
case 8:
|
||||
newSpreadingFactor = SX127X_SF_8;
|
||||
break;
|
||||
case 9:
|
||||
newSpreadingFactor = SX127X_SF_9;
|
||||
break;
|
||||
case 10:
|
||||
newSpreadingFactor = SX127X_SF_10;
|
||||
break;
|
||||
case 11:
|
||||
newSpreadingFactor = SX127X_SF_11;
|
||||
break;
|
||||
case 12:
|
||||
newSpreadingFactor = SX127X_SF_12;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_SPREADING_FACTOR);
|
||||
}
|
||||
|
||||
switch(cr) {
|
||||
case 5:
|
||||
newCodingRate = SX1278_CR_4_5;
|
||||
break;
|
||||
case 6:
|
||||
newCodingRate = SX1278_CR_4_6;
|
||||
break;
|
||||
case 7:
|
||||
newCodingRate = SX1278_CR_4_7;
|
||||
break;
|
||||
case 8:
|
||||
newCodingRate = SX1278_CR_4_8;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_CODING_RATE);
|
||||
}
|
||||
|
||||
if((freq < 137.0) || (freq > 1020.0)) {
|
||||
return(ERR_INVALID_FREQUENCY);
|
||||
}
|
||||
|
||||
// execute common part
|
||||
status = configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// configuration successful, save the new settings
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
15
src/modules/SX1276.h
Normal file
15
src/modules/SX1276.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef _KITELIB_SX1276_H
|
||||
#define _KITELIB_SX1276_H
|
||||
|
||||
#include "TypeDef.h"
|
||||
#include "SX1278.h"
|
||||
|
||||
class SX1276: public SX1278 {
|
||||
public:
|
||||
SX1276(Module* mod);
|
||||
|
||||
private:
|
||||
uint8_t config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord);
|
||||
};
|
||||
|
||||
#endif
|
76
src/modules/SX1277.cpp
Normal file
76
src/modules/SX1277.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include "SX1277.h"
|
||||
|
||||
SX1277::SX1277(Module* mod) : SX1278(mod) {
|
||||
|
||||
}
|
||||
|
||||
uint8_t SX1277::config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
|
||||
uint8_t status = ERR_NONE;
|
||||
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
|
||||
|
||||
// check the supplied BW, CR and SF values
|
||||
switch(bw) {
|
||||
case 125000:
|
||||
newBandwidth = SX1278_BW_125_00_KHZ;
|
||||
break;
|
||||
case 250000:
|
||||
newBandwidth = SX1278_BW_250_00_KHZ;
|
||||
break;
|
||||
case 500000:
|
||||
newBandwidth = SX1278_BW_500_00_KHZ;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_BANDWIDTH);
|
||||
}
|
||||
|
||||
switch(sf) {
|
||||
case 6:
|
||||
newSpreadingFactor = SX127X_SF_6;
|
||||
break;
|
||||
case 7:
|
||||
newSpreadingFactor = SX127X_SF_7;
|
||||
break;
|
||||
case 8:
|
||||
newSpreadingFactor = SX127X_SF_8;
|
||||
break;
|
||||
case 9:
|
||||
newSpreadingFactor = SX127X_SF_9;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_SPREADING_FACTOR);
|
||||
}
|
||||
|
||||
switch(cr) {
|
||||
case 5:
|
||||
newCodingRate = SX1278_CR_4_5;
|
||||
break;
|
||||
case 6:
|
||||
newCodingRate = SX1278_CR_4_6;
|
||||
break;
|
||||
case 7:
|
||||
newCodingRate = SX1278_CR_4_7;
|
||||
break;
|
||||
case 8:
|
||||
newCodingRate = SX1278_CR_4_8;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_CODING_RATE);
|
||||
}
|
||||
|
||||
if((freq < 137.0) || (freq > 1020.0)) {
|
||||
return(ERR_INVALID_FREQUENCY);
|
||||
}
|
||||
|
||||
// execute common part
|
||||
status = configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// configuration successful, save the new settings
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
15
src/modules/SX1277.h
Normal file
15
src/modules/SX1277.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef _KITELIB_SX1277_H
|
||||
#define _KITELIB_SX1277_H
|
||||
|
||||
#include "TypeDef.h"
|
||||
#include "SX1278.h"
|
||||
|
||||
class SX1277: public SX1278 {
|
||||
public:
|
||||
SX1277(Module* mod);
|
||||
|
||||
private:
|
||||
uint8_t config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,280 +1,76 @@
|
|||
#include "SX1278.h"
|
||||
|
||||
SX1278::SX1278(Module* module) {
|
||||
_mod = module;
|
||||
SX1278::SX1278(Module* mod) : SX127x(mod) {
|
||||
|
||||
}
|
||||
|
||||
uint8_t SX1278::begin(Bandwidth bw, SpreadingFactor sf, CodingRate cr, uint16_t addrEeprom) {
|
||||
// copy LoRa modem settings
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
|
||||
// ESP32-only: initialize EEPROM
|
||||
#ifdef ESP32
|
||||
if(!EEPROM.begin(9)) {
|
||||
DEBUG_PRINTLN_STR("Unable to initialize EEPROM");
|
||||
return(ERR_EEPROM_NOT_INITIALIZED);
|
||||
}
|
||||
#endif
|
||||
|
||||
// copy EEPROM start address
|
||||
_addrEeprom = addrEeprom;
|
||||
|
||||
// check if the node has address
|
||||
bool hasAddress = false;
|
||||
for(uint16_t i = 0; i < 8; i++) {
|
||||
if(EEPROM.read(_addrEeprom + i) != 255) {
|
||||
hasAddress = true;
|
||||
break;
|
||||
}
|
||||
uint8_t SX1278::begin(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t addrEeprom) {
|
||||
uint8_t state = SX127x::begin(freq, bw, sf, cr, syncWord, addrEeprom);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// generate new address
|
||||
if(!hasAddress) {
|
||||
randomSeed(analogRead(5));
|
||||
generateLoRaAdress();
|
||||
}
|
||||
|
||||
DEBUG_PRINTLN_STR("LoRa node address string: ");
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
_address[i] = EEPROM.read(i);
|
||||
#ifdef DEBUG
|
||||
Serial.print(_address[i], HEX);
|
||||
if(i < 7) {
|
||||
Serial.print(":");
|
||||
} else {
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// set module properties
|
||||
_mod->init(USE_SPI, INT_BOTH);
|
||||
|
||||
// try to find the SX1278 chip
|
||||
uint8_t i = 0;
|
||||
bool flagFound = false;
|
||||
while((i < 10) && !flagFound) {
|
||||
uint8_t version = _mod->SPIreadRegister(SX1278_REG_VERSION);
|
||||
if(version == 0x12) {
|
||||
flagFound = true;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
Serial.print("SX1278 not found! (");
|
||||
Serial.print(i + 1);
|
||||
Serial.print(" of 10 tries) SX1278_REG_VERSION == ");
|
||||
|
||||
char buffHex[5];
|
||||
sprintf(buffHex, "0x%02X", version);
|
||||
Serial.print(buffHex);
|
||||
Serial.println();
|
||||
#endif
|
||||
delay(1000);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flagFound) {
|
||||
DEBUG_PRINTLN_STR("No SX1278 found!");
|
||||
SPI.end();
|
||||
return(ERR_CHIP_NOT_FOUND);
|
||||
} else {
|
||||
DEBUG_PRINTLN_STR("Found SX1278! (match by SX1278_REG_VERSION == 0x12)");
|
||||
}
|
||||
|
||||
// configure LoRa modem
|
||||
return(config(_bw, _sf, _cr));
|
||||
return(config(freq, bw, sf, cr, syncWord));
|
||||
}
|
||||
|
||||
uint8_t SX1278::transmit(Packet& pack) {
|
||||
char buffer[256];
|
||||
|
||||
// copy packet source and destination addresses into buffer
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
buffer[i] = pack.source[i];
|
||||
buffer[i+8] = pack.destination[i];
|
||||
}
|
||||
|
||||
// copy packet data into buffer
|
||||
for(uint8_t i = 0; i < pack.length; i++) {
|
||||
buffer[i+16] = pack.data[i];
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
setMode(SX1278_STANDBY);
|
||||
|
||||
// set DIO pin mapping
|
||||
_mod->SPIsetRegValue(SX1278_REG_DIO_MAPPING_1, SX1278_DIO0_TX_DONE, 7, 6);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
// check overall packet length
|
||||
if(pack.length > 256) {
|
||||
return(ERR_PACKET_TOO_LONG);
|
||||
}
|
||||
|
||||
// write packet to FIFO
|
||||
_mod->SPIsetRegValue(SX1278_REG_PAYLOAD_LENGTH, pack.length);
|
||||
_mod->SPIsetRegValue(SX1278_REG_FIFO_TX_BASE_ADDR, SX1278_FIFO_TX_BASE_ADDR_MAX);
|
||||
_mod->SPIsetRegValue(SX1278_REG_FIFO_ADDR_PTR, SX1278_FIFO_TX_BASE_ADDR_MAX);
|
||||
_mod->SPIwriteRegisterBurstStr(SX1278_REG_FIFO, buffer, pack.length);
|
||||
|
||||
// set mode to transmit
|
||||
setMode(SX1278_TX);
|
||||
|
||||
// wait for transmission end
|
||||
unsigned long start = millis();
|
||||
while(!_mod->getInt0State()) {
|
||||
DEBUG_PRINT('.');
|
||||
}
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX1278::receive(Packet& pack) {
|
||||
char buffer[256];
|
||||
uint32_t startTime = millis();
|
||||
|
||||
// set mode to standby
|
||||
setMode(SX1278_STANDBY);
|
||||
|
||||
// set DIO pin mapping
|
||||
_mod->SPIsetRegValue(SX1278_REG_DIO_MAPPING_1, SX1278_DIO0_RX_DONE | SX1278_DIO1_RX_TIMEOUT, 7, 4);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
// set FIFO address pointers
|
||||
_mod->SPIsetRegValue(SX1278_REG_FIFO_RX_BASE_ADDR, SX1278_FIFO_RX_BASE_ADDR_MAX);
|
||||
_mod->SPIsetRegValue(SX1278_REG_FIFO_ADDR_PTR, SX1278_FIFO_RX_BASE_ADDR_MAX);
|
||||
|
||||
// set mode to receive
|
||||
setMode(SX1278_RXSINGLE);
|
||||
|
||||
// wait for packet reception or timeout
|
||||
while(!_mod->getInt0State()) {
|
||||
if(_mod->getInt1State()) {
|
||||
clearIRQFlags();
|
||||
return(ERR_RX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
// check received packet CRC
|
||||
if(_mod->SPIgetRegValue(SX1278_REG_IRQ_FLAGS, 5, 5) == SX1278_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR) {
|
||||
return(ERR_CRC_MISMATCH);
|
||||
}
|
||||
|
||||
// get header type
|
||||
uint8_t headerMode = _mod->SPIgetRegValue(SX1278_REG_MODEM_CONFIG_1, 0, 0);
|
||||
if(headerMode == SX1278_HEADER_EXPL_MODE) {
|
||||
pack.length = _mod->SPIgetRegValue(SX1278_REG_RX_NB_BYTES);
|
||||
}
|
||||
|
||||
// read packet from FIFO
|
||||
_mod->SPIreadRegisterBurstStr(SX1278_REG_FIFO, pack.length, buffer);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
// get packet source and destination addresses from buffer
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
pack.source[i] = buffer[i];
|
||||
pack.destination[i] = buffer[i+8];
|
||||
}
|
||||
|
||||
// get packet source and destination addresses from buffer
|
||||
for(uint8_t i = 16; i < pack.length; i++) {
|
||||
pack.data[i-16] = buffer[i];
|
||||
}
|
||||
pack.data[pack.length-16] = 0;
|
||||
|
||||
// measure overall datarate
|
||||
uint32_t elapsedTime = millis() - startTime;
|
||||
dataRate = (pack.length*8.0)/((float)elapsedTime/1000.0);
|
||||
|
||||
// get packet RSSI
|
||||
lastPacketRSSI = getLastPacketRSSI();
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX1278::sleep() {
|
||||
return(setMode(0b00000000));
|
||||
}
|
||||
|
||||
uint8_t SX1278::standby() {
|
||||
return(setMode(0b00000001));
|
||||
}
|
||||
|
||||
uint8_t SX1278::setBandwidth(Bandwidth bw) {
|
||||
uint8_t state = config(bw, _sf, _cr);
|
||||
uint8_t SX1278::setBandwidth(uint32_t bw) {
|
||||
uint8_t state = SX1278::config(bw, _sf, _cr, _freq, _syncWord);
|
||||
if(state == ERR_NONE) {
|
||||
_bw = bw;
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
uint8_t SX1278::setSpreadingFactor(SpreadingFactor sf) {
|
||||
uint8_t state = config(_bw, sf, _cr);
|
||||
uint8_t SX1278::setSpreadingFactor(uint8_t sf) {
|
||||
uint8_t state = SX1278::config(_bw, sf, _cr, _freq, _syncWord);
|
||||
if(state == ERR_NONE) {
|
||||
_sf = sf;
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
uint8_t SX1278::setCodingRate(CodingRate cr) {
|
||||
uint8_t state = config(_bw, _sf, cr);
|
||||
uint8_t SX1278::setCodingRate(uint8_t cr) {
|
||||
uint8_t state = SX1278::config(_bw, _sf, cr, _freq, _syncWord);
|
||||
if(state == ERR_NONE) {
|
||||
_cr = cr;
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
void SX1278::generateLoRaAdress() {
|
||||
for(uint8_t i = _addrEeprom; i < (_addrEeprom + 8); i++) {
|
||||
EEPROM.write(i, (uint8_t)random(0, 256));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t SX1278::config(Bandwidth bw, SpreadingFactor sf, CodingRate cr) {
|
||||
uint8_t SX1278::config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord) {
|
||||
uint8_t status = ERR_NONE;
|
||||
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
|
||||
|
||||
//check the supplied bw, cr and sf values
|
||||
// check the supplied BW, CR and SF values
|
||||
switch(bw) {
|
||||
case BW_7_80_KHZ:
|
||||
case 7800:
|
||||
newBandwidth = SX1278_BW_7_80_KHZ;
|
||||
break;
|
||||
case BW_10_40_KHZ:
|
||||
case 10400:
|
||||
newBandwidth = SX1278_BW_10_40_KHZ;
|
||||
break;
|
||||
case BW_15_60_KHZ:
|
||||
case 15600:
|
||||
newBandwidth = SX1278_BW_15_60_KHZ;
|
||||
break;
|
||||
case BW_20_80_KHZ:
|
||||
case 20800:
|
||||
newBandwidth = SX1278_BW_20_80_KHZ;
|
||||
break;
|
||||
case BW_31_25_KHZ:
|
||||
case 31250:
|
||||
newBandwidth = SX1278_BW_31_25_KHZ;
|
||||
break;
|
||||
case BW_41_70_KHZ:
|
||||
case 41700:
|
||||
newBandwidth = SX1278_BW_41_70_KHZ;
|
||||
break;
|
||||
case BW_62_50_KHZ:
|
||||
case 62500:
|
||||
newBandwidth = SX1278_BW_62_50_KHZ;
|
||||
break;
|
||||
case BW_125_00_KHZ:
|
||||
case 125000:
|
||||
newBandwidth = SX1278_BW_125_00_KHZ;
|
||||
break;
|
||||
case BW_250_00_KHZ:
|
||||
case 250000:
|
||||
newBandwidth = SX1278_BW_250_00_KHZ;
|
||||
break;
|
||||
case BW_500_00_KHZ:
|
||||
case 500000:
|
||||
newBandwidth = SX1278_BW_500_00_KHZ;
|
||||
break;
|
||||
default:
|
||||
|
@ -282,130 +78,107 @@ uint8_t SX1278::config(Bandwidth bw, SpreadingFactor sf, CodingRate cr) {
|
|||
}
|
||||
|
||||
switch(sf) {
|
||||
case SF_6:
|
||||
newSpreadingFactor = SX1278_SF_6;
|
||||
case 6:
|
||||
newSpreadingFactor = SX127X_SF_6;
|
||||
break;
|
||||
case SF_7:
|
||||
newSpreadingFactor = SX1278_SF_7;
|
||||
case 7:
|
||||
newSpreadingFactor = SX127X_SF_7;
|
||||
break;
|
||||
case SF_8:
|
||||
newSpreadingFactor = SX1278_SF_8;
|
||||
case 8:
|
||||
newSpreadingFactor = SX127X_SF_8;
|
||||
break;
|
||||
case SF_9:
|
||||
newSpreadingFactor = SX1278_SF_9;
|
||||
case 9:
|
||||
newSpreadingFactor = SX127X_SF_9;
|
||||
break;
|
||||
case SF_10:
|
||||
newSpreadingFactor = SX1278_SF_10;
|
||||
case 10:
|
||||
newSpreadingFactor = SX127X_SF_10;
|
||||
break;
|
||||
case SF_11:
|
||||
newSpreadingFactor = SX1278_SF_11;
|
||||
case 11:
|
||||
newSpreadingFactor = SX127X_SF_11;
|
||||
break;
|
||||
case SF_12:
|
||||
newSpreadingFactor = SX1278_SF_12;
|
||||
case 12:
|
||||
newSpreadingFactor = SX127X_SF_12;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_SPREADING_FACTOR);
|
||||
}
|
||||
|
||||
switch(cr) {
|
||||
case CR_4_5:
|
||||
case 5:
|
||||
newCodingRate = SX1278_CR_4_5;
|
||||
break;
|
||||
case CR_4_6:
|
||||
case 6:
|
||||
newCodingRate = SX1278_CR_4_6;
|
||||
break;
|
||||
case CR_4_7:
|
||||
case 7:
|
||||
newCodingRate = SX1278_CR_4_7;
|
||||
break;
|
||||
case CR_4_8:
|
||||
case 8:
|
||||
newCodingRate = SX1278_CR_4_8;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_CODING_RATE);
|
||||
}
|
||||
|
||||
// set mode to SLEEP
|
||||
status = setMode(SX1278_SLEEP);
|
||||
if((freq < 137.0) || (freq > 525.0)) {
|
||||
return(ERR_INVALID_FREQUENCY);
|
||||
}
|
||||
|
||||
// execute common part
|
||||
status = SX1278::configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// set LoRa mode
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_OP_MODE, SX1278_LORA, 7, 7);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
// configuration successful, save the new settings
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
_freq = freq;
|
||||
|
||||
// set carrier frequency
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_FRF_MSB, SX1278_FRF_MSB);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_FRF_MID, SX1278_FRF_MID);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_FRF_LSB, SX1278_FRF_LSB);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX1278::configCommon(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
|
||||
// configure common registers
|
||||
uint8_t status = SX127x::config(bw, sf, cr, freq, syncWord);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// output power configuration
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_PA_CONFIG, SX1278_PA_SELECT_BOOST | SX1278_MAX_POWER | SX1278_OUTPUT_POWER);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_OCP, SX1278_OCP_ON | SX1278_OCP_TRIM, 5, 0);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_LNA, SX1278_LNA_GAIN_1 | SX1278_LNA_BOOST_HF_ON);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX1278_PA_BOOST_ON, 2, 0);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX1278_MAX_POWER, 6, 4);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// turn off frequency hopping
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_HOP_PERIOD, SX1278_HOP_PERIOD_OFF);
|
||||
// enable LNA gain setting by register
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_AGC_AUTO_OFF, 2, 2);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// basic setting (bw, cr, sf, header mode and CRC)
|
||||
if(newSpreadingFactor == SX1278_SF_6) {
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_2, SX1278_SF_6 | SX1278_TX_MODE_SINGLE | SX1278_RX_CRC_MODE_OFF, 7, 2);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_1, newBandwidth | newCodingRate | SX1278_HEADER_IMPL_MODE);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_DETECT_OPTIMIZE, SX1278_DETECT_OPTIMIZE_SF_6, 2, 0);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_DETECTION_THRESHOLD, SX1278_DETECTION_THRESHOLD_SF_6);
|
||||
// calculate symbol length and set low datarate optimization, if needed
|
||||
uint16_t base = 1;
|
||||
float symbolLength = (float)(base << _sf) / (float)_bw;
|
||||
if(symbolLength >= 0.016) {
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_ON, 0, 0);
|
||||
} else {
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_2, newSpreadingFactor | SX1278_TX_MODE_SINGLE | SX1278_RX_CRC_MODE_ON, 7, 2);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_1, newBandwidth | newCodingRate | SX1278_HEADER_EXPL_MODE);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_DETECT_OPTIMIZE, SX1278_DETECT_OPTIMIZE_SF_7_12, 2, 0);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_DETECTION_THRESHOLD, SX1278_DETECTION_THRESHOLD_SF_7_12);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_OFF, 0, 0);
|
||||
}
|
||||
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// set default preamble length
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_PREAMBLE_MSB, SX1278_PREAMBLE_LENGTH_MSB);
|
||||
status = _mod->SPIsetRegValue(SX1278_REG_PREAMBLE_LSB, SX1278_PREAMBLE_LENGTH_LSB);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
// set SF6 optimizations
|
||||
if(sf == SX127X_SF_6) {
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1278_RX_CRC_MODE_OFF, 2, 2);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, bw | cr | SX1278_HEADER_IMPL_MODE);
|
||||
} else {
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1278_RX_CRC_MODE_ON, 2, 2);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, bw | cr | SX1278_HEADER_EXPL_MODE);
|
||||
}
|
||||
|
||||
// set mode to STANDBY
|
||||
status = setMode(SX1278_STANDBY);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// save the new settings
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX1278::setMode(uint8_t mode) {
|
||||
_mod->SPIsetRegValue(SX1278_REG_OP_MODE, mode, 2, 0);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void SX1278::clearIRQFlags() {
|
||||
_mod->SPIwriteRegister(SX1278_REG_IRQ_FLAGS, 0b11111111);
|
||||
}
|
||||
|
||||
int8_t SX1278::getLastPacketRSSI() {
|
||||
return(-164 + _mod->SPIgetRegValue(SX1278_REG_PKT_RSSI_VALUE));
|
||||
return(status);
|
||||
}
|
||||
|
|
|
@ -1,59 +1,12 @@
|
|||
#ifndef _KITELIB_SX1278_H
|
||||
#define _KITELIB_SX1278_H
|
||||
|
||||
#include <EEPROM.h>
|
||||
|
||||
#include "TypeDef.h"
|
||||
#include "Module.h"
|
||||
#include "Packet.h"
|
||||
#include "SX127x.h"
|
||||
|
||||
//SX1278 register map
|
||||
#define SX1278_REG_FIFO 0x00
|
||||
#define SX1278_REG_OP_MODE 0x01
|
||||
#define SX1278_REG_FRF_MSB 0x06
|
||||
#define SX1278_REG_FRF_MID 0x07
|
||||
#define SX1278_REG_FRF_LSB 0x08
|
||||
#define SX1278_REG_PA_CONFIG 0x09
|
||||
#define SX1278_REG_PA_RAMP 0x0A
|
||||
#define SX1278_REG_OCP 0x0B
|
||||
#define SX1278_REG_LNA 0x0C
|
||||
#define SX1278_REG_FIFO_ADDR_PTR 0x0D
|
||||
#define SX1278_REG_FIFO_TX_BASE_ADDR 0x0E
|
||||
#define SX1278_REG_FIFO_RX_BASE_ADDR 0x0F
|
||||
#define SX1278_REG_FIFO_RX_CURRENT_ADDR 0x10
|
||||
#define SX1278_REG_IRQ_FLAGS_MASK 0x11
|
||||
#define SX1278_REG_IRQ_FLAGS 0x12
|
||||
#define SX1278_REG_RX_NB_BYTES 0x13
|
||||
#define SX1278_REG_RX_HEADER_CNT_VALUE_MSB 0x14
|
||||
#define SX1278_REG_RX_HEADER_CNT_VALUE_LSB 0x15
|
||||
#define SX1278_REG_RX_PACKET_CNT_VALUE_MSB 0x16
|
||||
#define SX1278_REG_RX_PACKET_CNT_VALUE_LSB 0x17
|
||||
#define SX1278_REG_MODEM_STAT 0x18
|
||||
#define SX1278_REG_PKT_SNR_VALUE 0x19
|
||||
#define SX1278_REG_PKT_RSSI_VALUE 0x1A
|
||||
#define SX1278_REG_RSSI_VALUE 0x1B
|
||||
#define SX1278_REG_HOP_CHANNEL 0x1C
|
||||
#define SX1278_REG_MODEM_CONFIG_1 0x1D
|
||||
#define SX1278_REG_MODEM_CONFIG_2 0x1E
|
||||
#define SX1278_REG_SYMB_TIMEOUT_LSB 0x1F
|
||||
#define SX1278_REG_PREAMBLE_MSB 0x20
|
||||
#define SX1278_REG_PREAMBLE_LSB 0x21
|
||||
#define SX1278_REG_PAYLOAD_LENGTH 0x22
|
||||
#define SX1278_REG_MAX_PAYLOAD_LENGTH 0x23
|
||||
#define SX1278_REG_HOP_PERIOD 0x24
|
||||
#define SX1278_REG_FIFO_RX_BYTE_ADDR 0x25
|
||||
//SX1278 specific register map
|
||||
#define SX1278_REG_MODEM_CONFIG_3 0x26
|
||||
#define SX1278_REG_FEI_MSB 0x28
|
||||
#define SX1278_REG_FEI_MID 0x29
|
||||
#define SX1278_REG_FEI_LSB 0x2A
|
||||
#define SX1278_REG_RSSI_WIDEBAND 0x2C
|
||||
#define SX1278_REG_DETECT_OPTIMIZE 0x31
|
||||
#define SX1278_REG_INVERT_IQ 0x33
|
||||
#define SX1278_REG_DETECTION_THRESHOLD 0x37
|
||||
#define SX1278_REG_SYNC_WORD 0x39
|
||||
#define SX1278_REG_DIO_MAPPING_1 0x40
|
||||
#define SX1278_REG_DIO_MAPPING_2 0x41
|
||||
#define SX1278_REG_VERSION 0x42
|
||||
#define SX1278_REG_TCXO 0x4B
|
||||
#define SX1278_REG_PA_DAC 0x4D
|
||||
#define SX1278_REG_FORMER_TEMP 0x5D
|
||||
|
@ -65,20 +18,8 @@
|
|||
|
||||
//SX1278 LoRa modem settings
|
||||
//SX1278_REG_OP_MODE MSB LSB DESCRIPTION
|
||||
#define SX1278_FSK_OOK 0b00000000 // 7 7 FSK/OOK mode
|
||||
#define SX1278_LORA 0b10000000 // 7 7 LoRa mode
|
||||
#define SX1278_ACCESS_SHARED_REG_OFF 0b00000000 // 6 6 access LoRa registers (0x0D:0x3F) in LoRa mode
|
||||
#define SX1278_ACCESS_SHARED_REG_ON 0b01000000 // 6 6 access FSK registers (0x0D:0x3F) in LoRa mode
|
||||
#define SX1278_HIGH_FREQ 0b00000000 // 3 3 access HF test registers
|
||||
#define SX1278_LOW_FREQ 0b00001000 // 3 3 access LF test registers
|
||||
#define SX1278_SLEEP 0b00000000 // 2 0 sleep
|
||||
#define SX1278_STANDBY 0b00000001 // 2 0 standby
|
||||
#define SX1278_FSTX 0b00000010 // 2 0 frequency synthesis TX
|
||||
#define SX1278_TX 0b00000011 // 2 0 transmit
|
||||
#define SX1278_FSRX 0b00000100 // 2 0 frequency synthesis RX
|
||||
#define SX1278_RXCONTINUOUS 0b00000101 // 2 0 receive continuous
|
||||
#define SX1278_RXSINGLE 0b00000110 // 2 0 receive single
|
||||
#define SX1278_CAD 0b00000111 // 2 0 channel activity detection
|
||||
|
||||
//SX1278_REG_FRF_MSB + REG_FRF_MID + REG_FRF_LSB
|
||||
#define SX1278_FRF_MSB 0x6C // 7 0 carrier frequency setting: f_RF = (F(XOSC) * FRF)/2^19
|
||||
|
@ -86,28 +27,10 @@
|
|||
#define SX1278_FRF_LSB 0x00 // 7 0 FRF = 3 byte value of FRF registers
|
||||
|
||||
//SX1278_REG_PA_CONFIG
|
||||
#define SX1278_PA_SELECT_RFO 0b00000000 // 7 7 RFO pin output, power limited to +14 dBm
|
||||
#define SX1278_PA_SELECT_BOOST 0b10000000 // 7 7 PA_BOOST pin output, power limited to +20 dBm
|
||||
#define SX1278_MAX_POWER 0b01110000 // 6 4 max power: P_max = 10.8 + 0.6*MAX_POWER [dBm]; P_max(MAX_POWER = 0b111) = 15 dBm
|
||||
#define SX1278_OUTPUT_POWER 0b00001111 // 3 0 output power: P_out = 17 - (15 - OUTPUT_POWER) [dBm] for PA_SELECT_BOOST
|
||||
|
||||
//SX1278_REG_OCP
|
||||
#define SX1278_OCP_OFF 0b00000000 // 5 5 PA overload current protection disabled
|
||||
#define SX1278_OCP_ON 0b00100000 // 5 5 PA overload current protection enabled
|
||||
#define SX1278_OCP_TRIM 0b00001011 // 4 0 OCP current: I_max(OCP_TRIM = 0b1011) = 100 mA
|
||||
|
||||
//SX1278_REG_LNA
|
||||
#define SX1278_LNA_GAIN_0 0b00000000 // 7 5 LNA gain setting: not used
|
||||
#define SX1278_LNA_GAIN_1 0b00100000 // 7 5 max gain
|
||||
#define SX1278_LNA_GAIN_2 0b01000000 // 7 5 .
|
||||
#define SX1278_LNA_GAIN_3 0b01100000 // 7 5 .
|
||||
#define SX1278_LNA_GAIN_4 0b10000000 // 7 5 .
|
||||
#define SX1278_LNA_GAIN_5 0b10100000 // 7 5 .
|
||||
#define SX1278_LNA_GAIN_6 0b11000000 // 7 5 min gain
|
||||
#define SX1278_LNA_GAIN_7 0b11100000 // 7 5 not used
|
||||
#define SX1278_LNA_BOOST_LF_OFF 0b00000000 // 4 3 default LNA current
|
||||
#define SX1278_LNA_BOOST_HF_OFF 0b00000000 // 1 0 default LNA current
|
||||
#define SX1278_LNA_BOOST_HF_ON 0b00000011 // 1 0 150% LNA current
|
||||
|
||||
//SX1278_REG_MODEM_CONFIG_1
|
||||
#define SX1278_BW_7_80_KHZ 0b00000000 // 7 4 bandwidth: 7.80 kHz
|
||||
|
@ -128,25 +51,8 @@
|
|||
#define SX1278_HEADER_IMPL_MODE 0b00000001 // 0 0 implicit header mode
|
||||
|
||||
//SX1278_REG_MODEM_CONFIG_2
|
||||
#define SX1278_SF_6 0b01100000 // 7 4 spreading factor: 64 chips/bit
|
||||
#define SX1278_SF_7 0b01110000 // 7 4 128 chips/bit
|
||||
#define SX1278_SF_8 0b10000000 // 7 4 256 chips/bit
|
||||
#define SX1278_SF_9 0b10010000 // 7 4 512 chips/bit
|
||||
#define SX1278_SF_10 0b10100000 // 7 4 1024 chips/bit
|
||||
#define SX1278_SF_11 0b10110000 // 7 4 2048 chips/bit
|
||||
#define SX1278_SF_12 0b11000000 // 7 4 4096 chips/bit
|
||||
#define SX1278_TX_MODE_SINGLE 0b00000000 // 3 3 single TX
|
||||
#define SX1278_TX_MODE_CONT 0b00001000 // 3 3 continuous TX
|
||||
#define SX1278_RX_CRC_MODE_OFF 0b00000000 // 2 2 CRC disabled
|
||||
#define SX1278_RX_CRC_MODE_ON 0b00000100 // 2 2 CRC enabled
|
||||
#define SX1278_RX_TIMEOUT_MSB 0b00000000 // 1 0
|
||||
|
||||
//SX1278_REG_SYMB_TIMEOUT_LSB
|
||||
#define SX1278_RX_TIMEOUT_LSB 0b01100100 // 7 0 10 bit RX operation timeout
|
||||
|
||||
//SX1278_REG_PREAMBLE_MSB + REG_PREAMBLE_LSB
|
||||
#define SX1278_PREAMBLE_LENGTH_MSB 0b00000000 // 7 0 2 byte preamble length setting: l_P = PREAMBLE_LENGTH + 4.25
|
||||
#define SX1278_PREAMBLE_LENGTH_LSB 0b00001000 // 7 0 where l_p = preamble length
|
||||
|
||||
//SX1278_REG_MODEM_CONFIG_3
|
||||
#define SX1278_LOW_DATA_RATE_OPT_OFF 0b00000000 // 3 3 low data rate optimization disabled
|
||||
|
@ -154,89 +60,21 @@
|
|||
#define SX1278_AGC_AUTO_OFF 0b00000000 // 2 2 LNA gain set by REG_LNA
|
||||
#define SX1278_AGC_AUTO_ON 0b00000100 // 2 2 LNA gain set by internal AGC loop
|
||||
|
||||
//SX1278_REG_DETECT_OPTIMIZE
|
||||
#define SX1278_DETECT_OPTIMIZE_SF_6 0b00000101 // 2 0 SF6 detection optimization
|
||||
#define SX1278_DETECT_OPTIMIZE_SF_7_12 0b00000011 // 2 0 SF7 to SF12 detection optimization
|
||||
|
||||
//SX1278_REG_DETECTION_THRESHOLD
|
||||
#define SX1278_DETECTION_THRESHOLD_SF_6 0b00001100 // 7 0 SF6 detection threshold
|
||||
#define SX1278_DETECTION_THRESHOLD_SF_7_12 0b00001010 // 7 0 SF7 to SF12 detection threshold
|
||||
|
||||
//SX1278_REG_PA_DAC
|
||||
#define SX1278_PA_BOOST_OFF 0b00000100 // 2 0 PA_BOOST disabled
|
||||
#define SX1278_PA_BOOST_ON 0b00000111 // 2 0 +20 dBm on PA_BOOST when OUTPUT_POWER = 0b1111
|
||||
|
||||
//SX1278_REG_HOP_PERIOD
|
||||
#define SX1278_HOP_PERIOD_OFF 0b00000000 // 7 0 number of periods between frequency hops; 0 = disabled
|
||||
#define SX1278_HOP_PERIOD_MAX 0b11111111 // 7 0
|
||||
|
||||
//SX1278_REG_DIO_MAPPING_1
|
||||
#define SX1278_DIO0_RX_DONE 0b00000000 // 7 6
|
||||
#define SX1278_DIO0_TX_DONE 0b01000000 // 7 6
|
||||
#define SX1278_DIO0_CAD_DONE 0b10000000 // 7 6
|
||||
#define SX1278_DIO1_RX_TIMEOUT 0b00000000 // 5 4
|
||||
#define SX1278_DIO1_FHSS_CHANGE_CHANNEL 0b00010000 // 5 4
|
||||
#define SX1278_DIO1_CAD_DETECTED 0b00100000 // 5 4
|
||||
|
||||
//SX1278_REG_IRQ_FLAGS
|
||||
#define SX1278_CLEAR_IRQ_FLAG_RX_TIMEOUT 0b10000000 // 7 7 timeout
|
||||
#define SX1278_CLEAR_IRQ_FLAG_RX_DONE 0b01000000 // 6 6 packet reception complete
|
||||
#define SX1278_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR 0b00100000 // 5 5 payload CRC error
|
||||
#define SX1278_CLEAR_IRQ_FLAG_VALID_HEADER 0b00010000 // 4 4 valid header received
|
||||
#define SX1278_CLEAR_IRQ_FLAG_TX_DONE 0b00001000 // 3 3 payload transmission complete
|
||||
#define SX1278_CLEAR_IRQ_FLAG_CAD_DONE 0b00000100 // 2 2 CAD complete
|
||||
#define SX1278_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL 0b00000010 // 1 1 FHSS change channel
|
||||
#define SX1278_CLEAR_IRQ_FLAG_CAD_DETECTED 0b00000001 // 0 0 valid LoRa signal detected during CAD operation
|
||||
|
||||
//SX1278_REG_IRQ_FLAGS_MASK
|
||||
#define SX1278_MASK_IRQ_FLAG_RX_TIMEOUT 0b01111111 // 7 7 timeout
|
||||
#define SX1278_MASK_IRQ_FLAG_RX_DONE 0b10111111 // 6 6 packet reception complete
|
||||
#define SX1278_MASK_IRQ_FLAG_PAYLOAD_CRC_ERROR 0b11011111 // 5 5 payload CRC error
|
||||
#define SX1278_MASK_IRQ_FLAG_VALID_HEADER 0b11101111 // 4 4 valid header received
|
||||
#define SX1278_MASK_IRQ_FLAG_TX_DONE 0b11110111 // 3 3 payload transmission complete
|
||||
#define SX1278_MASK_IRQ_FLAG_CAD_DONE 0b11111011 // 2 2 CAD complete
|
||||
#define SX1278_MASK_IRQ_FLAG_FHSS_CHANGE_CHANNEL 0b11111101 // 1 1 FHSS change channel
|
||||
#define SX1278_MASK_IRQ_FLAG_CAD_DETECTED 0b11111110 // 0 0 valid LoRa signal detected during CAD operation
|
||||
|
||||
//SX1278_REG_FIFO_TX_BASE_ADDR
|
||||
#define SX1278_FIFO_TX_BASE_ADDR_MAX 0b00000000 // 7 0 allocate the entire FIFO buffer for TX only
|
||||
|
||||
//SX1278_REG_FIFO_RX_BASE_ADDR
|
||||
#define SX1278_FIFO_RX_BASE_ADDR_MAX 0b00000000 // 7 0 allocate the entire FIFO buffer for RX only
|
||||
|
||||
class SX1278 {
|
||||
class SX1278: public SX127x {
|
||||
public:
|
||||
SX1278(Module* module);
|
||||
SX1278(Module* mod);
|
||||
|
||||
float dataRate;
|
||||
int8_t lastPacketRSSI;
|
||||
uint8_t begin(float freq = 434.0, uint32_t bw = 125000, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = SX127X_SYNC_WORD, uint16_t addrEeprom = 0);
|
||||
|
||||
uint8_t begin(Bandwidth bw = BW_125_00_KHZ, SpreadingFactor sf = SF_9, CodingRate cr = CR_4_7, uint16_t addrEeprom = 0);
|
||||
uint8_t transmit(Packet& pack);
|
||||
uint8_t receive(Packet& pack);
|
||||
|
||||
uint8_t sleep();
|
||||
uint8_t standby();
|
||||
|
||||
uint8_t setBandwidth(Bandwidth bw);
|
||||
uint8_t setSpreadingFactor(SpreadingFactor sf);
|
||||
uint8_t setCodingRate(CodingRate cr);
|
||||
uint8_t setBandwidth(uint32_t bw);
|
||||
uint8_t setSpreadingFactor(uint8_t sf);
|
||||
uint8_t setCodingRate(uint8_t cr);
|
||||
|
||||
protected:
|
||||
uint8_t configCommon(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord); // common for SX1276/77/78/79
|
||||
|
||||
private:
|
||||
Module* _mod;
|
||||
|
||||
Bandwidth _bw;
|
||||
SpreadingFactor _sf;
|
||||
CodingRate _cr;
|
||||
|
||||
uint16_t _addrEeprom;
|
||||
uint8_t _address[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
void generateLoRaAdress();
|
||||
uint8_t config(Bandwidth bw, SpreadingFactor sf, CodingRate cr);
|
||||
uint8_t setMode(uint8_t mode);
|
||||
void clearIRQFlags();
|
||||
int8_t getLastPacketRSSI();
|
||||
uint8_t config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord); // specific to SX1278
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
76
src/modules/SX1279.cpp
Normal file
76
src/modules/SX1279.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include "SX1279.h"
|
||||
|
||||
SX1279::SX1279(Module* mod) : SX1278(mod) {
|
||||
|
||||
}
|
||||
|
||||
uint8_t SX1279::config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
|
||||
uint8_t status = ERR_NONE;
|
||||
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
|
||||
|
||||
// check the supplied BW, CR and SF values
|
||||
switch(bw) {
|
||||
case 125000:
|
||||
newBandwidth = SX1278_BW_125_00_KHZ;
|
||||
break;
|
||||
case 250000:
|
||||
newBandwidth = SX1278_BW_250_00_KHZ;
|
||||
break;
|
||||
case 500000:
|
||||
newBandwidth = SX1278_BW_500_00_KHZ;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_BANDWIDTH);
|
||||
}
|
||||
|
||||
switch(sf) {
|
||||
case 6:
|
||||
newSpreadingFactor = SX127X_SF_6;
|
||||
break;
|
||||
case 7:
|
||||
newSpreadingFactor = SX127X_SF_7;
|
||||
break;
|
||||
case 8:
|
||||
newSpreadingFactor = SX127X_SF_8;
|
||||
break;
|
||||
case 9:
|
||||
newSpreadingFactor = SX127X_SF_9;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_SPREADING_FACTOR);
|
||||
}
|
||||
|
||||
switch(cr) {
|
||||
case 5:
|
||||
newCodingRate = SX1278_CR_4_5;
|
||||
break;
|
||||
case 6:
|
||||
newCodingRate = SX1278_CR_4_6;
|
||||
break;
|
||||
case 7:
|
||||
newCodingRate = SX1278_CR_4_7;
|
||||
break;
|
||||
case 8:
|
||||
newCodingRate = SX1278_CR_4_8;
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_CODING_RATE);
|
||||
}
|
||||
|
||||
if((freq < 137.0) || (freq > 960.0)) {
|
||||
return(ERR_INVALID_FREQUENCY);
|
||||
}
|
||||
|
||||
// execute common part
|
||||
status = configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// configuration successful, save the new settings
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
15
src/modules/SX1279.h
Normal file
15
src/modules/SX1279.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef _KITELIB_SX1279_H
|
||||
#define _KITELIB_SX1279_H
|
||||
|
||||
#include "TypeDef.h"
|
||||
#include "SX1278.h"
|
||||
|
||||
class SX1279: public SX1278 {
|
||||
public:
|
||||
SX1279(Module* mod);
|
||||
|
||||
private:
|
||||
uint8_t config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord);
|
||||
};
|
||||
|
||||
#endif
|
327
src/modules/SX127x.cpp
Normal file
327
src/modules/SX127x.cpp
Normal file
|
@ -0,0 +1,327 @@
|
|||
#include "SX127x.h"
|
||||
|
||||
SX127x::SX127x(Module* mod) {
|
||||
_mod = mod;
|
||||
}
|
||||
|
||||
uint8_t SX127x::begin(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t addrEeprom) {
|
||||
// copy LoRa modem settings
|
||||
_freq = freq;
|
||||
_bw = bw;
|
||||
_sf = sf;
|
||||
_cr = cr;
|
||||
_syncWord = syncWord;
|
||||
|
||||
// ESP32-only: initialize EEPROM
|
||||
#ifdef ESP32
|
||||
if(!EEPROM.begin(9)) {
|
||||
DEBUG_PRINTLN_STR("Unable to initialize EEPROM");
|
||||
return(ERR_EEPROM_NOT_INITIALIZED);
|
||||
}
|
||||
#endif
|
||||
|
||||
// copy EEPROM start address
|
||||
_addrEeprom = addrEeprom;
|
||||
|
||||
// check if the node has address
|
||||
bool hasAddress = false;
|
||||
for(uint16_t i = 0; i < 8; i++) {
|
||||
if(EEPROM.read(_addrEeprom + i) != 255) {
|
||||
hasAddress = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// generate new address
|
||||
if(!hasAddress) {
|
||||
randomSeed(analogRead(5));
|
||||
generateNodeAdress();
|
||||
}
|
||||
|
||||
DEBUG_PRINTLN_STR("LoRa node address string: ");
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
_address[i] = EEPROM.read(i);
|
||||
#ifdef KITELIB_DEBUG
|
||||
Serial.print(_address[i], HEX);
|
||||
if(i < 7) {
|
||||
Serial.print(":");
|
||||
} else {
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// set module properties
|
||||
_mod->init(USE_SPI, INT_BOTH);
|
||||
|
||||
// try to find the SX127x chip
|
||||
uint8_t i = 0;
|
||||
bool flagFound = false;
|
||||
while((i < 10) && !flagFound) {
|
||||
uint8_t version = _mod->SPIreadRegister(SX127X_REG_VERSION);
|
||||
if(version == 0x12) {
|
||||
flagFound = true;
|
||||
} else {
|
||||
#ifdef KITELIB_DEBUG
|
||||
Serial.print("SX127x not found! (");
|
||||
Serial.print(i + 1);
|
||||
Serial.print(" of 10 tries) SX127X_REG_VERSION == ");
|
||||
|
||||
char buffHex[5];
|
||||
sprintf(buffHex, "0x%02X", version);
|
||||
Serial.print(buffHex);
|
||||
Serial.println();
|
||||
#endif
|
||||
delay(1000);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!flagFound) {
|
||||
DEBUG_PRINTLN_STR("No SX127x found!");
|
||||
SPI.end();
|
||||
return(ERR_CHIP_NOT_FOUND);
|
||||
} else {
|
||||
DEBUG_PRINTLN_STR("Found SX127x! (match by SX127X_REG_VERSION == 0x12)");
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX127x::transmit(Packet& pack) {
|
||||
// check packet length
|
||||
if(pack.length >= 256) {
|
||||
return(ERR_PACKET_TOO_LONG);
|
||||
}
|
||||
|
||||
// calculate timeout
|
||||
uint16_t base = 1;
|
||||
float symbolLength = (float)(base << _sf) / (float)_bw;
|
||||
float de = 0;
|
||||
if(symbolLength >= 0.016) {
|
||||
de = 1;
|
||||
}
|
||||
float ih = (float)_mod->SPIgetRegValue(SX127X_REG_MODEM_CONFIG_1, 0, 0);
|
||||
float crc = (float)(_mod->SPIgetRegValue(SX127X_REG_MODEM_CONFIG_2, 2, 2) >> 2);
|
||||
float n_pre = (float)_mod->SPIgetRegValue(SX127X_REG_PREAMBLE_LSB);
|
||||
float n_pay = 8.0 + max(ceil((8.0 * (float)pack.length - 4.0 * (float)_sf + 28.0 + 16.0 * crc - 20.0 * ih)/(4.0 * (float)_sf - 8.0 * de)) * (float)_cr, 0);
|
||||
uint32_t timeout = ceil(symbolLength * (n_pre + n_pay + 4.25) * 1000.0);
|
||||
|
||||
// write packet to FIFO
|
||||
setMode(SX127X_STANDBY);
|
||||
|
||||
_mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_TX_DONE, 7, 6);
|
||||
clearIRQFlags();
|
||||
|
||||
_mod->SPIsetRegValue(SX127X_REG_PAYLOAD_LENGTH, pack.length);
|
||||
_mod->SPIsetRegValue(SX127X_REG_FIFO_TX_BASE_ADDR, SX127X_FIFO_TX_BASE_ADDR_MAX);
|
||||
_mod->SPIsetRegValue(SX127X_REG_FIFO_ADDR_PTR, SX127X_FIFO_TX_BASE_ADDR_MAX);
|
||||
|
||||
_mod->SPIwriteRegisterBurstStr(SX127X_REG_FIFO, pack.source, 8);
|
||||
_mod->SPIwriteRegisterBurstStr(SX127X_REG_FIFO, pack.destination, 8);
|
||||
_mod->SPIwriteRegisterBurstStr(SX127X_REG_FIFO, pack.data, pack.length - 16);
|
||||
|
||||
// start transmission
|
||||
setMode(SX127X_TX);
|
||||
|
||||
// check for timeout
|
||||
uint32_t start = millis();
|
||||
while(!_mod->getInt0State()) {
|
||||
if(millis() - start > timeout) {
|
||||
clearIRQFlags();
|
||||
return(ERR_TX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
clearIRQFlags();
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX127x::receive(Packet& pack) {
|
||||
// prepare for packet reception
|
||||
setMode(SX127X_STANDBY);
|
||||
|
||||
_mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_RX_DONE | SX127X_DIO1_RX_TIMEOUT, 7, 4);
|
||||
clearIRQFlags();
|
||||
|
||||
_mod->SPIsetRegValue(SX127X_REG_FIFO_RX_BASE_ADDR, SX127X_FIFO_RX_BASE_ADDR_MAX);
|
||||
_mod->SPIsetRegValue(SX127X_REG_FIFO_ADDR_PTR, SX127X_FIFO_RX_BASE_ADDR_MAX);
|
||||
|
||||
// start receiving
|
||||
setMode(SX127X_RXSINGLE);
|
||||
|
||||
uint32_t start = millis();
|
||||
while(!_mod->getInt0State()) {
|
||||
if(_mod->getInt1State()) {
|
||||
clearIRQFlags();
|
||||
return(ERR_RX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
uint32_t elapsed = millis() - start;
|
||||
|
||||
if(_mod->SPIgetRegValue(SX127X_REG_IRQ_FLAGS, 5, 5) == SX127X_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR) {
|
||||
return(ERR_CRC_MISMATCH);
|
||||
}
|
||||
|
||||
if(_sf != 6) {
|
||||
pack.length = _mod->SPIgetRegValue(SX127X_REG_RX_NB_BYTES);
|
||||
}
|
||||
|
||||
_mod->SPIreadRegisterBurstStr(SX127X_REG_FIFO, 8, pack.source);
|
||||
_mod->SPIreadRegisterBurstStr(SX127X_REG_FIFO, 8, pack.destination);
|
||||
|
||||
delete[] pack.data;
|
||||
pack.data = new char[pack.length - 15];
|
||||
_mod->SPIreadRegisterBurstStr(SX127X_REG_FIFO, pack.length - 16, pack.data);
|
||||
pack.data[pack.length - 16] = 0;
|
||||
|
||||
dataRate = (pack.length*8.0)/((float)elapsed/1000.0);
|
||||
lastPacketRSSI = -157 + _mod->SPIgetRegValue(SX127X_REG_PKT_RSSI_VALUE);
|
||||
int8_t rawSNR = (int8_t)_mod->SPIgetRegValue(SX127X_REG_PKT_SNR_VALUE);
|
||||
lastPacketSNR = rawSNR / 4.0;
|
||||
|
||||
clearIRQFlags();
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
uint8_t SX127x::scanChannel() {
|
||||
setMode(SX127X_STANDBY);
|
||||
|
||||
_mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_CAD_DONE | SX127X_DIO1_CAD_DETECTED, 7, 4);
|
||||
clearIRQFlags();
|
||||
|
||||
setMode(SX127X_CAD);
|
||||
|
||||
while(!_mod->getInt0State()) {
|
||||
if(_mod->getInt1State()) {
|
||||
clearIRQFlags();
|
||||
return(PREAMBLE_DETECTED);
|
||||
}
|
||||
}
|
||||
|
||||
clearIRQFlags();
|
||||
return(CHANNEL_FREE);
|
||||
}
|
||||
|
||||
uint8_t SX127x::sleep() {
|
||||
return(setMode(SX127X_SLEEP));
|
||||
}
|
||||
|
||||
uint8_t SX127x::standby() {
|
||||
return(setMode(SX127X_STANDBY));
|
||||
}
|
||||
|
||||
uint8_t SX127x::setFrequency(float freq) {
|
||||
uint8_t state = config(_bw, _sf, _cr, freq, _syncWord);
|
||||
if(state == ERR_NONE) {
|
||||
_freq = freq;
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
uint8_t SX127x::setSyncWord(uint8_t syncWord) {
|
||||
uint8_t state = config(_bw, _sf, _cr, _freq, syncWord);
|
||||
if(state == ERR_NONE) {
|
||||
_syncWord = syncWord;
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
uint8_t SX127x::setOutputPower(int8_t power) {
|
||||
setMode(SX127X_STANDBY);
|
||||
|
||||
if((power < 2) || (power > 17)) {
|
||||
return(ERR_INVALID_OUTPUT_POWER);
|
||||
}
|
||||
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, power - 2, 3, 0));
|
||||
}
|
||||
|
||||
uint8_t SX127x::config(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
|
||||
uint8_t status = ERR_NONE;
|
||||
|
||||
// set mode to SLEEP
|
||||
status = setMode(SX127X_SLEEP);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// set LoRa mode
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX127X_LORA, 7, 7);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// set carrier frequency
|
||||
uint32_t base = 1;
|
||||
uint32_t FRF = (freq * (base << 19)) / 32.0;
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_FRF_MSB, (FRF & 0xFF0000) >> 16);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_FRF_MID, (FRF & 0x00FF00) >> 8);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_FRF_LSB, FRF & 0x0000FF);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// output power configuration
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST | SX127X_OUTPUT_POWER);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_OCP, SX127X_OCP_ON | SX127X_OCP_TRIM, 5, 0);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_LNA, SX127X_LNA_GAIN_1 | SX127X_LNA_BOOST_ON);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// turn off frequency hopping
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_HOP_PERIOD, SX127X_HOP_PERIOD_OFF);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// basic setting (bw, cr, sf, header mode and CRC)
|
||||
if(sf == SX127X_SF_6) {
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX127X_SF_6 | SX127X_TX_MODE_SINGLE, 7, 3);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_6, 2, 0);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_6);
|
||||
} else {
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, sf | SX127X_TX_MODE_SINGLE, 7, 3);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_7_12, 2, 0);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_7_12);
|
||||
}
|
||||
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// set the sync word
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_SYNC_WORD, syncWord);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// set default preamble length
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_PREAMBLE_MSB, SX127X_PREAMBLE_LENGTH_MSB);
|
||||
status = _mod->SPIsetRegValue(SX127X_REG_PREAMBLE_LSB, SX127X_PREAMBLE_LENGTH_LSB);
|
||||
if(status != ERR_NONE) {
|
||||
return(status);
|
||||
}
|
||||
|
||||
// set mode to STANDBY
|
||||
status = setMode(SX127X_STANDBY);
|
||||
return(status);
|
||||
}
|
||||
|
||||
void SX127x::generateNodeAdress() {
|
||||
for(uint8_t i = _addrEeprom; i < (_addrEeprom + 8); i++) {
|
||||
EEPROM.write(i, (uint8_t)random(0, 256));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t SX127x::setMode(uint8_t mode) {
|
||||
_mod->SPIsetRegValue(SX127X_REG_OP_MODE, mode, 2, 0);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void SX127x::clearIRQFlags() {
|
||||
_mod->SPIwriteRegister(SX127X_REG_IRQ_FLAGS, 0b11111111);
|
||||
}
|
211
src/modules/SX127x.h
Normal file
211
src/modules/SX127x.h
Normal file
|
@ -0,0 +1,211 @@
|
|||
#ifndef _KITELIB_SX127X_H
|
||||
#define _KITELIB_SX127X_H
|
||||
|
||||
#include <EEPROM.h>
|
||||
|
||||
#include "TypeDef.h"
|
||||
#include "Module.h"
|
||||
#include "Packet.h"
|
||||
|
||||
// SX127x series common registers
|
||||
#define SX127X_REG_FIFO 0x00
|
||||
#define SX127X_REG_OP_MODE 0x01
|
||||
#define SX127X_REG_FRF_MSB 0x06
|
||||
#define SX127X_REG_FRF_MID 0x07
|
||||
#define SX127X_REG_FRF_LSB 0x08
|
||||
#define SX127X_REG_PA_CONFIG 0x09
|
||||
#define SX127X_REG_PA_RAMP 0x0A
|
||||
#define SX127X_REG_OCP 0x0B
|
||||
#define SX127X_REG_LNA 0x0C
|
||||
#define SX127X_REG_FIFO_ADDR_PTR 0x0D
|
||||
#define SX127X_REG_FIFO_TX_BASE_ADDR 0x0E
|
||||
#define SX127X_REG_FIFO_RX_BASE_ADDR 0x0F
|
||||
#define SX127X_REG_FIFO_RX_CURRENT_ADDR 0x10
|
||||
#define SX127X_REG_IRQ_FLAGS_MASK 0x11
|
||||
#define SX127X_REG_IRQ_FLAGS 0x12
|
||||
#define SX127X_REG_RX_NB_BYTES 0x13
|
||||
#define SX127X_REG_RX_HEADER_CNT_VALUE_MSB 0x14
|
||||
#define SX127X_REG_RX_HEADER_CNT_VALUE_LSB 0x15
|
||||
#define SX127X_REG_RX_PACKET_CNT_VALUE_MSB 0x16
|
||||
#define SX127X_REG_RX_PACKET_CNT_VALUE_LSB 0x17
|
||||
#define SX127X_REG_MODEM_STAT 0x18
|
||||
#define SX127X_REG_PKT_SNR_VALUE 0x19
|
||||
#define SX127X_REG_PKT_RSSI_VALUE 0x1A
|
||||
#define SX127X_REG_RSSI_VALUE 0x1B
|
||||
#define SX127X_REG_HOP_CHANNEL 0x1C
|
||||
#define SX127X_REG_MODEM_CONFIG_1 0x1D
|
||||
#define SX127X_REG_MODEM_CONFIG_2 0x1E
|
||||
#define SX127X_REG_SYMB_TIMEOUT_LSB 0x1F
|
||||
#define SX127X_REG_PREAMBLE_MSB 0x20
|
||||
#define SX127X_REG_PREAMBLE_LSB 0x21
|
||||
#define SX127X_REG_PAYLOAD_LENGTH 0x22
|
||||
#define SX127X_REG_MAX_PAYLOAD_LENGTH 0x23
|
||||
#define SX127X_REG_HOP_PERIOD 0x24
|
||||
#define SX127X_REG_FIFO_RX_BYTE_ADDR 0x25
|
||||
#define SX127X_REG_FEI_MSB 0x28
|
||||
#define SX127X_REG_FEI_MID 0x29
|
||||
#define SX127X_REG_FEI_LSB 0x2A
|
||||
#define SX127X_REG_RSSI_WIDEBAND 0x2C
|
||||
#define SX127X_REG_DETECT_OPTIMIZE 0x31
|
||||
#define SX127X_REG_INVERT_IQ 0x33
|
||||
#define SX127X_REG_DETECTION_THRESHOLD 0x37
|
||||
#define SX127X_REG_SYNC_WORD 0x39
|
||||
#define SX127X_REG_DIO_MAPPING_1 0x40
|
||||
#define SX127X_REG_DIO_MAPPING_2 0x41
|
||||
#define SX127X_REG_VERSION 0x42
|
||||
|
||||
// SX127x common modem settings
|
||||
// SX127X_REG_OP_MODE MSB LSB DESCRIPTION
|
||||
#define SX127X_FSK_OOK 0b00000000 // 7 7 FSK/OOK mode
|
||||
#define SX127X_LORA 0b10000000 // 7 7 LoRa mode
|
||||
#define SX127X_ACCESS_SHARED_REG_OFF 0b00000000 // 6 6 access LoRa registers (0x0D:0x3F) in LoRa mode
|
||||
#define SX127X_ACCESS_SHARED_REG_ON 0b01000000 // 6 6 access FSK registers (0x0D:0x3F) in LoRa mode
|
||||
#define SX127X_SLEEP 0b00000000 // 2 0 sleep
|
||||
#define SX127X_STANDBY 0b00000001 // 2 0 standby
|
||||
#define SX127X_FSTX 0b00000010 // 2 0 frequency synthesis TX
|
||||
#define SX127X_TX 0b00000011 // 2 0 transmit
|
||||
#define SX127X_FSRX 0b00000100 // 2 0 frequency synthesis RX
|
||||
#define SX127X_RXCONTINUOUS 0b00000101 // 2 0 receive continuous
|
||||
#define SX127X_RXSINGLE 0b00000110 // 2 0 receive single
|
||||
#define SX127X_CAD 0b00000111 // 2 0 channel activity detection
|
||||
|
||||
// SX127X_REG_PA_CONFIG
|
||||
#define SX127X_PA_SELECT_RFO 0b00000000 // 7 7 RFO pin output, power limited to +14 dBm
|
||||
#define SX127X_PA_SELECT_BOOST 0b10000000 // 7 7 PA_BOOST pin output, power limited to +20 dBm
|
||||
#define SX127X_OUTPUT_POWER 0b00001111 // 3 0 output power: P_out = 2 + OUTPUT_POWER [dBm] for PA_SELECT_BOOST
|
||||
// P_out = -1 + OUTPUT_POWER [dBm] for PA_SELECT_RFO
|
||||
|
||||
// SX127X_REG_OCP
|
||||
#define SX127X_OCP_OFF 0b00000000 // 5 5 PA overload current protection disabled
|
||||
#define SX127X_OCP_ON 0b00100000 // 5 5 PA overload current protection enabled
|
||||
#define SX127X_OCP_TRIM 0b00001011 // 4 0 OCP current: I_max(OCP_TRIM = 0b1011) = 100 mA
|
||||
|
||||
// SX127X_REG_LNA
|
||||
#define SX127X_LNA_GAIN_0 0b00000000 // 7 5 LNA gain setting: not used
|
||||
#define SX127X_LNA_GAIN_1 0b00100000 // 7 5 max gain
|
||||
#define SX127X_LNA_GAIN_2 0b01000000 // 7 5 .
|
||||
#define SX127X_LNA_GAIN_3 0b01100000 // 7 5 .
|
||||
#define SX127X_LNA_GAIN_4 0b10000000 // 7 5 .
|
||||
#define SX127X_LNA_GAIN_5 0b10100000 // 7 5 .
|
||||
#define SX127X_LNA_GAIN_6 0b11000000 // 7 5 min gain
|
||||
#define SX127X_LNA_GAIN_7 0b11100000 // 7 5 not used
|
||||
#define SX127X_LNA_BOOST_OFF 0b00000000 // 1 0 default LNA current
|
||||
#define SX127X_LNA_BOOST_ON 0b00000011 // 1 0 150% LNA current
|
||||
|
||||
// SX127X_REG_MODEM_CONFIG_2
|
||||
#define SX127X_SF_6 0b01100000 // 7 4 spreading factor: 64 chips/bit
|
||||
#define SX127X_SF_7 0b01110000 // 7 4 128 chips/bit
|
||||
#define SX127X_SF_8 0b10000000 // 7 4 256 chips/bit
|
||||
#define SX127X_SF_9 0b10010000 // 7 4 512 chips/bit
|
||||
#define SX127X_SF_10 0b10100000 // 7 4 1024 chips/bit
|
||||
#define SX127X_SF_11 0b10110000 // 7 4 2048 chips/bit
|
||||
#define SX127X_SF_12 0b11000000 // 7 4 4096 chips/bit
|
||||
#define SX127X_TX_MODE_SINGLE 0b00000000 // 3 3 single TX
|
||||
#define SX127X_TX_MODE_CONT 0b00001000 // 3 3 continuous TX
|
||||
#define SX127X_RX_TIMEOUT_MSB 0b00000000 // 1 0
|
||||
|
||||
// SX127X_REG_SYMB_TIMEOUT_LSB
|
||||
#define SX127X_RX_TIMEOUT_LSB 0b01100100 // 7 0 10 bit RX operation timeout
|
||||
|
||||
// SX127X_REG_PREAMBLE_MSB + REG_PREAMBLE_LSB
|
||||
#define SX127X_PREAMBLE_LENGTH_MSB 0b00000000 // 7 0 2 byte preamble length setting: l_P = PREAMBLE_LENGTH + 4.25
|
||||
#define SX127X_PREAMBLE_LENGTH_LSB 0b00001000 // 7 0 where l_p = preamble length
|
||||
|
||||
// SX127X_REG_DETECT_OPTIMIZE
|
||||
#define SX127X_DETECT_OPTIMIZE_SF_6 0b00000101 // 2 0 SF6 detection optimization
|
||||
#define SX127X_DETECT_OPTIMIZE_SF_7_12 0b00000011 // 2 0 SF7 to SF12 detection optimization
|
||||
|
||||
// SX127X_REG_DETECTION_THRESHOLD
|
||||
#define SX127X_DETECTION_THRESHOLD_SF_6 0b00001100 // 7 0 SF6 detection threshold
|
||||
#define SX127X_DETECTION_THRESHOLD_SF_7_12 0b00001010 // 7 0 SF7 to SF12 detection threshold
|
||||
|
||||
// SX127X_REG_PA_DAC
|
||||
#define SX127X_PA_BOOST_OFF 0b00000100 // 2 0 PA_BOOST disabled
|
||||
#define SX127X_PA_BOOST_ON 0b00000111 // 2 0 +20 dBm on PA_BOOST when OUTPUT_POWER = 0b1111
|
||||
|
||||
// SX127X_REG_HOP_PERIOD
|
||||
#define SX127X_HOP_PERIOD_OFF 0b00000000 // 7 0 number of periods between frequency hops; 0 = disabled
|
||||
#define SX127X_HOP_PERIOD_MAX 0b11111111 // 7 0
|
||||
|
||||
// SX127X_REG_DIO_MAPPING_1
|
||||
#define SX127X_DIO0_RX_DONE 0b00000000 // 7 6
|
||||
#define SX127X_DIO0_TX_DONE 0b01000000 // 7 6
|
||||
#define SX127X_DIO0_CAD_DONE 0b10000000 // 7 6
|
||||
#define SX127X_DIO1_RX_TIMEOUT 0b00000000 // 5 4
|
||||
#define SX127X_DIO1_FHSS_CHANGE_CHANNEL 0b00010000 // 5 4
|
||||
#define SX127X_DIO1_CAD_DETECTED 0b00100000 // 5 4
|
||||
|
||||
// SX127X_REG_IRQ_FLAGS
|
||||
#define SX127X_CLEAR_IRQ_FLAG_RX_TIMEOUT 0b10000000 // 7 7 timeout
|
||||
#define SX127X_CLEAR_IRQ_FLAG_RX_DONE 0b01000000 // 6 6 packet reception complete
|
||||
#define SX127X_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR 0b00100000 // 5 5 payload CRC error
|
||||
#define SX127X_CLEAR_IRQ_FLAG_VALID_HEADER 0b00010000 // 4 4 valid header received
|
||||
#define SX127X_CLEAR_IRQ_FLAG_TX_DONE 0b00001000 // 3 3 payload transmission complete
|
||||
#define SX127X_CLEAR_IRQ_FLAG_CAD_DONE 0b00000100 // 2 2 CAD complete
|
||||
#define SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL 0b00000010 // 1 1 FHSS change channel
|
||||
#define SX127X_CLEAR_IRQ_FLAG_CAD_DETECTED 0b00000001 // 0 0 valid LoRa signal detected during CAD operation
|
||||
|
||||
// SX127X_REG_IRQ_FLAGS_MASK
|
||||
#define SX127X_MASK_IRQ_FLAG_RX_TIMEOUT 0b01111111 // 7 7 timeout
|
||||
#define SX127X_MASK_IRQ_FLAG_RX_DONE 0b10111111 // 6 6 packet reception complete
|
||||
#define SX127X_MASK_IRQ_FLAG_PAYLOAD_CRC_ERROR 0b11011111 // 5 5 payload CRC error
|
||||
#define SX127X_MASK_IRQ_FLAG_VALID_HEADER 0b11101111 // 4 4 valid header received
|
||||
#define SX127X_MASK_IRQ_FLAG_TX_DONE 0b11110111 // 3 3 payload transmission complete
|
||||
#define SX127X_MASK_IRQ_FLAG_CAD_DONE 0b11111011 // 2 2 CAD complete
|
||||
#define SX127X_MASK_IRQ_FLAG_FHSS_CHANGE_CHANNEL 0b11111101 // 1 1 FHSS change channel
|
||||
#define SX127X_MASK_IRQ_FLAG_CAD_DETECTED 0b11111110 // 0 0 valid LoRa signal detected during CAD operation
|
||||
|
||||
// SX127X_REG_FIFO_TX_BASE_ADDR
|
||||
#define SX127X_FIFO_TX_BASE_ADDR_MAX 0b00000000 // 7 0 allocate the entire FIFO buffer for TX only
|
||||
|
||||
// SX127X_REG_FIFO_RX_BASE_ADDR
|
||||
#define SX127X_FIFO_RX_BASE_ADDR_MAX 0b00000000 // 7 0 allocate the entire FIFO buffer for RX only
|
||||
|
||||
// SX127X_REG_SYNC_WORD
|
||||
#define SX127X_SYNC_WORD 0x12 // 7 0 default LoRa sync word
|
||||
#define SX127X_SYNC_WORD_LORAWAN 0x34 // 7 0 sync word reserved for LoRaWAN networks
|
||||
|
||||
class SX127x {
|
||||
public:
|
||||
SX127x(Module* mod);
|
||||
|
||||
float dataRate;
|
||||
int8_t lastPacketRSSI;
|
||||
float lastPacketSNR;
|
||||
|
||||
uint8_t begin(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t addrEeprom);
|
||||
uint8_t transmit(Packet& pack);
|
||||
uint8_t receive(Packet& pack);
|
||||
uint8_t scanChannel();
|
||||
|
||||
uint8_t sleep();
|
||||
uint8_t standby();
|
||||
|
||||
uint8_t setFrequency(float freq);
|
||||
uint8_t setSyncWord(uint8_t syncWord);
|
||||
uint8_t setOutputPower(int8_t power);
|
||||
|
||||
protected:
|
||||
Module* _mod;
|
||||
|
||||
uint32_t _bw;
|
||||
uint8_t _sf;
|
||||
uint8_t _cr;
|
||||
float _freq;
|
||||
uint8_t _syncWord;
|
||||
|
||||
uint8_t tx(char* data, uint8_t length);
|
||||
uint8_t rxSingle(char* data, uint8_t* length);
|
||||
|
||||
uint8_t config(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord);
|
||||
|
||||
private:
|
||||
uint8_t _address[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
uint16_t _addrEeprom;
|
||||
|
||||
void generateNodeAdress();
|
||||
uint8_t setMode(uint8_t mode);
|
||||
void clearIRQFlags();
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue