1
0
mirror of https://github.com/sandeepmistry/arduino-LoRa.git synced 2025-04-19 13:02:14 +03:00

Merge branch 'master' into fix-ISR-not-in-IRAM

This commit is contained in:
Anthony Elder 2019-06-08 10:31:45 +01:00
commit 1cf44e5bb9
12 changed files with 481 additions and 40 deletions

View File

@ -9,6 +9,7 @@ env:
- BOARD="arduino:samd:arduino_zero_edbg" - BOARD="arduino:samd:arduino_zero_edbg"
- BOARD="arduino:samd:mkr1000" - BOARD="arduino:samd:mkr1000"
- BOARD="arduino:samd:mkrzero" - BOARD="arduino:samd:mkrzero"
- BOARD="arduino:samd:mkrwan1300"
before_install: before_install:
- wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz - wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz
- tar xf arduino-$IDE_VERSION-linux64.tar.xz - tar xf arduino-$IDE_VERSION-linux64.tar.xz
@ -24,9 +25,14 @@ install:
script: script:
- buildExampleSketch LoRaDumpRegisters - buildExampleSketch LoRaDumpRegisters
- buildExampleSketch LoRaDuplex - buildExampleSketch LoRaDuplex
- buildExampleSketch LoRaDuplexCallback - if [[ "$BOARD" != "arduino:samd:mkrwan1300" ]]; then
buildExampleSketch LoRaDuplexCallback;
fi
- buildExampleSketch LoRaReceiver - buildExampleSketch LoRaReceiver
- buildExampleSketch LoRaReceiverCallback - if [[ "$BOARD" != "arduino:samd:mkrwan1300" ]]; then
buildExampleSketch LoRaReceiverCallback;
fi
- buildExampleSketch LoRaSender - buildExampleSketch LoRaSender
- buildExampleSketch LoRaSenderNonBlocking
- buildExampleSketch LoRaSetSpread - buildExampleSketch LoRaSetSpread
- buildExampleSketch LoRaSetSyncWord - buildExampleSketch LoRaSetSyncWord

34
API.md
View File

@ -38,6 +38,17 @@ To save further pins one could connect the reset pin of the MCU with reset pin o
* `reset` - set to `-1` to omit this pin * `reset` - set to `-1` to omit this pin
### Set SPI interface
Override the default SPI interface used by the library. **Must** be called before `LoRa.begin()`.
```arduino
LoRa.setSPI(spi);
```
* `spi` - new SPI interface to use, defaults to `SPI`
This call is optional and only needs to be used if you need to change the default SPI interface used, in the case your Arduino (or compatible) board has more than one SPI interface present.
### Set SPI Frequency ### Set SPI Frequency
Override the default SPI frequency of 10 MHz used by the library. **Must** be called before `LoRa.begin()`. Override the default SPI frequency of 10 MHz used by the library. **Must** be called before `LoRa.begin()`.
@ -71,7 +82,7 @@ LoRa.beginPacket(implicitHeader);
* `implicitHeader` - (optional) `true` enables implicit header mode, `false` enables explicit header mode (default) * `implicitHeader` - (optional) `true` enables implicit header mode, `false` enables explicit header mode (default)
Returns `1` on success, `0` on failure. Returns `1` if radio is ready to transmit, `0` if busy or on failure.
### Writing ### Writing
@ -98,8 +109,11 @@ Returns the number of bytes written.
End the sequence of sending a packet. End the sequence of sending a packet.
```arduino ```arduino
LoRa.endPacket() LoRa.endPacket();
LoRa.endPacket(async);
``` ```
* `async` - (optional) `true` enables non-blocking mode, `false` waits for transmission to be completed (default)
Returns `1` on success, `0` on failure. Returns `1` on success, `0` on failure.
@ -122,6 +136,8 @@ Returns the packet size in bytes or `0` if no packet was received.
### Continuous receive mode ### Continuous receive mode
**WARNING**: Not supported on the Arduino MKR WAN 1300 board!
#### Register callback #### Register callback
Register a callback function for when a packet is received. Register a callback function for when a packet is received.
@ -236,7 +252,7 @@ LoRa.setTxPower(txPower, outputPin);
* `txPower` - TX power in dB, defaults to `17` * `txPower` - TX power in dB, defaults to `17`
* `outputPin` - (optional) PA output pin, supported values are `PA_OUTPUT_RFO_PIN` and `PA_OUTPUT_PA_BOOST_PIN`, defaults to `PA_OUTPUT_PA_BOOST_PIN`. * `outputPin` - (optional) PA output pin, supported values are `PA_OUTPUT_RFO_PIN` and `PA_OUTPUT_PA_BOOST_PIN`, defaults to `PA_OUTPUT_PA_BOOST_PIN`.
Supported values are between `2` and `17` for `PA_OUTPUT_PA_BOOST_PIN`, `0` and `14` for `PA_OUTPUT_RFO_PIN`. Supported values are `2` to `20` for `PA_OUTPUT_PA_BOOST_PIN`, and `0` to `14` for `PA_OUTPUT_RFO_PIN`.
Most modules have the PA output pin connected to PA BOOST, Most modules have the PA output pin connected to PA BOOST,
@ -304,7 +320,7 @@ Change the sync word of the radio.
LoRa.setSyncWord(syncWord); LoRa.setSyncWord(syncWord);
``` ```
* `syncWord` - byte value to use as the sync word, defaults to `0x34` * `syncWord` - byte value to use as the sync word, defaults to `0x12`
### CRC ### CRC
@ -316,6 +332,16 @@ LoRa.enableCrc();
LoRa.disableCrc(); LoRa.disableCrc();
``` ```
### Invert IQ Signals
Enable or disable Invert the LoRa I and Q signals, by default a invertIQ is not used.
```arduino
LoRa.enableInvertIQ();
LoRa.disableInvertIQ();
```
## Other functions ## Other functions
### Random ### Random

View File

@ -10,6 +10,9 @@ An [Arduino](https://arduino.cc/) library for sending and receiving data using [
* [Dragino Lora Shield](http://www.dragino.com/products/module/item/102-lora-shield.html) * [Dragino Lora Shield](http://www.dragino.com/products/module/item/102-lora-shield.html)
* [HopeRF](http://www.hoperf.com/rf_transceiver/lora/) [RFM95W](http://www.hoperf.com/rf_transceiver/lora/RFM95W.html), [RFM96W](http://www.hoperf.com/rf_transceiver/lora/RFM96W.html), and [RFM98W](http://www.hoperf.com/rf_transceiver/lora/RFM98W.html) * [HopeRF](http://www.hoperf.com/rf_transceiver/lora/) [RFM95W](http://www.hoperf.com/rf_transceiver/lora/RFM95W.html), [RFM96W](http://www.hoperf.com/rf_transceiver/lora/RFM96W.html), and [RFM98W](http://www.hoperf.com/rf_transceiver/lora/RFM98W.html)
* [Modtronix](http://modtronix.com/) [inAir4](http://modtronix.com/inair4.html), [inAir9](http://modtronix.com/inair9.html), and [inAir9B](http://modtronix.com/inair9b.html) * [Modtronix](http://modtronix.com/) [inAir4](http://modtronix.com/inair4.html), [inAir9](http://modtronix.com/inair9.html), and [inAir9B](http://modtronix.com/inair9b.html)
* [Arduino MKR WAN 1300](https://store.arduino.cc/usa/mkr-wan-1300)
* **NOTE:** Requires firmware v1.1.6 or later on the on-board Murata module. Please use the [MKRWANFWUpdate_standalone example](https://github.com/arduino-libraries/MKRWAN/blob/master/examples/MKRWANFWUpdate_standalone/MKRWANFWUpdate_standalone.ino) from latest [MKRWAN library](https://github.com/arduino-libraries/MKRWAN) release to update the firmware.
* **WARNING**: [LoRa.onReceive(...)](https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md#register-callback) and [LoRa.recieve()](https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md#receive-mode) is not compatible with this board!
### Semtech SX1276/77/78/79 wiring ### Semtech SX1276/77/78/79 wiring

View File

@ -15,6 +15,10 @@
#include <SPI.h> // include libraries #include <SPI.h> // include libraries
#include <LoRa.h> #include <LoRa.h>
#ifdef ARDUINO_SAMD_MKRWAN1300
#error "This example is not compatible with the Arduino MKR WAN 1300 board!"
#endif
const int csPin = 7; // LoRa radio chip select const int csPin = 7; // LoRa radio chip select
const int resetPin = 6; // LoRa radio reset const int resetPin = 6; // LoRa radio reset
const int irqPin = 1; // change for your board; must be a hardware interrupt pin const int irqPin = 1; // change for your board; must be a hardware interrupt pin

View File

@ -1,6 +1,10 @@
#include <SPI.h> #include <SPI.h>
#include <LoRa.h> #include <LoRa.h>
#ifdef ARDUINO_SAMD_MKRWAN1300
#error "This example is not compatible with the Arduino MKR WAN 1300 board!"
#endif
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
while (!Serial); while (!Serial);

View File

@ -0,0 +1,35 @@
#include <SPI.h>
#include <LoRa.h>
int counter = 0;
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("LoRa Sender non-blocking");
if (!LoRa.begin(915E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
// wait until the radio is ready to send a packet
while (LoRa.beginPacket() == 0) {
Serial.print("waiting for radio ... ");
delay(100);
}
Serial.print("Sending packet non-blocking: ");
Serial.println(counter);
// send in async / non-blocking mode
LoRa.beginPacket();
LoRa.print("hello ");
LoRa.print(counter);
LoRa.endPacket(true); // true = async / non-blocking mode
counter++;
}

View File

@ -0,0 +1,113 @@
/*
LoRa Simple Gateway/Node Exemple
This code uses InvertIQ function to create a simple Gateway/Node logic.
Gateway - Sends messages with enableInvertIQ()
- Receives messages with disableInvertIQ()
Node - Sends messages with disableInvertIQ()
- Receives messages with enableInvertIQ()
With this arrangement a Gateway never receive messages from another Gateway
and a Node never receive message from another Node.
Only Gateway to Node and vice versa.
This code receives messages and sends a message every second.
InvertIQ function basically invert the LoRa I and Q signals.
See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf
for more on InvertIQ register 0x33.
created 05 August 2018
by Luiz H. Cassettari
*/
#include <SPI.h> // include libraries
#include <LoRa.h>
const long frequency = 915E6; // LoRa Frequency
const int csPin = 10; // LoRa radio chip select
const int resetPin = 9; // LoRa radio reset
const int irqPin = 2; // change for your board; must be a hardware interrupt pin
void setup() {
Serial.begin(9600); // initialize serial
while (!Serial);
LoRa.setPins(csPin, resetPin, irqPin);
if (!LoRa.begin(frequency)) {
Serial.println("LoRa init failed. Check your connections.");
while (true); // if failed, do nothing
}
Serial.println("LoRa init succeeded.");
Serial.println();
Serial.println("LoRa Simple Gateway");
Serial.println("Only receive messages from nodes");
Serial.println("Tx: invertIQ enable");
Serial.println("Rx: invertIQ disable");
Serial.println();
LoRa.onReceive(onReceive);
LoRa_rxMode();
}
void loop() {
if (runEvery(5000)) { // repeat every 5000 millis
String message = "HeLoRa World! ";
message += "I'm a Gateway! ";
message += millis();
LoRa_sendMessage(message); // send a message
Serial.println("Send Message!");
}
}
void LoRa_rxMode(){
LoRa.disableInvertIQ(); // normal mode
LoRa.receive(); // set receive mode
}
void LoRa_txMode(){
LoRa.idle(); // set standby mode
LoRa.enableInvertIQ(); // active invert I and Q signals
}
void LoRa_sendMessage(String message) {
LoRa_txMode(); // set tx mode
LoRa.beginPacket(); // start packet
LoRa.print(message); // add payload
LoRa.endPacket(); // finish packet and send it
LoRa_rxMode(); // set rx mode
}
void onReceive(int packetSize) {
String message = "";
while (LoRa.available()) {
message += (char)LoRa.read();
}
Serial.print("Gateway Receive: ");
Serial.println(message);
}
boolean runEvery(unsigned long interval)
{
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
return true;
}
return false;
}

View File

@ -0,0 +1,113 @@
/*
LoRa Simple Gateway/Node Exemple
This code uses InvertIQ function to create a simple Gateway/Node logic.
Gateway - Sends messages with enableInvertIQ()
- Receives messages with disableInvertIQ()
Node - Sends messages with disableInvertIQ()
- Receives messages with enableInvertIQ()
With this arrangement a Gateway never receive messages from another Gateway
and a Node never receive message from another Node.
Only Gateway to Node and vice versa.
This code receives messages and sends a message every second.
InvertIQ function basically invert the LoRa I and Q signals.
See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf
for more on InvertIQ register 0x33.
created 05 August 2018
by Luiz H. Cassettari
*/
#include <SPI.h> // include libraries
#include <LoRa.h>
const long frequency = 915E6; // LoRa Frequency
const int csPin = 10; // LoRa radio chip select
const int resetPin = 9; // LoRa radio reset
const int irqPin = 2; // change for your board; must be a hardware interrupt pin
void setup() {
Serial.begin(9600); // initialize serial
while (!Serial);
LoRa.setPins(csPin, resetPin, irqPin);
if (!LoRa.begin(frequency)) {
Serial.println("LoRa init failed. Check your connections.");
while (true); // if failed, do nothing
}
Serial.println("LoRa init succeeded.");
Serial.println();
Serial.println("LoRa Simple Node");
Serial.println("Only receive messages from gateways");
Serial.println("Tx: invertIQ disable");
Serial.println("Rx: invertIQ enable");
Serial.println();
LoRa.onReceive(onReceive);
LoRa_rxMode();
}
void loop() {
if (runEvery(1000)) { // repeat every 1000 millis
String message = "HeLoRa World! ";
message += "I'm a Node! ";
message += millis();
LoRa_sendMessage(message); // send a message
Serial.println("Send Message!");
}
}
void LoRa_rxMode(){
LoRa.enableInvertIQ(); // active invert I and Q signals
LoRa.receive(); // set receive mode
}
void LoRa_txMode(){
LoRa.idle(); // set standby mode
LoRa.disableInvertIQ(); // normal mode
}
void LoRa_sendMessage(String message) {
LoRa_txMode(); // set tx mode
LoRa.beginPacket(); // start packet
LoRa.print(message); // add payload
LoRa.endPacket(); // finish packet and send it
LoRa_rxMode(); // set rx mode
}
void onReceive(int packetSize) {
String message = "";
while (LoRa.available()) {
message += (char)LoRa.read();
}
Serial.print("Node Receive: ");
Serial.println(message);
}
boolean runEvery(unsigned long interval)
{
static unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
previousMillis = currentMillis;
return true;
}
return false;
}

View File

@ -44,6 +44,8 @@ setPreambleLength KEYWORD2
setSyncWord KEYWORD2 setSyncWord KEYWORD2
enableCrc KEYWORD2 enableCrc KEYWORD2
disableCrc KEYWORD2 disableCrc KEYWORD2
enableInvertIQ KEYWORD2
disableInvertIQ KEYWORD2
random KEYWORD2 random KEYWORD2
setPins KEYWORD2 setPins KEYWORD2

View File

@ -1,5 +1,5 @@
name=LoRa name=LoRa
version=0.3.0 version=0.5.0
author=Sandeep Mistry <sandeep.mistry@gmail.com> author=Sandeep Mistry <sandeep.mistry@gmail.com>
maintainer=Sandeep Mistry <sandeep.mistry@gmail.com> maintainer=Sandeep Mistry <sandeep.mistry@gmail.com>
sentence=An Arduino library for sending and receiving data using LoRa radios. sentence=An Arduino library for sending and receiving data using LoRa radios.

View File

@ -10,6 +10,7 @@
#define REG_FRF_MID 0x07 #define REG_FRF_MID 0x07
#define REG_FRF_LSB 0x08 #define REG_FRF_LSB 0x08
#define REG_PA_CONFIG 0x09 #define REG_PA_CONFIG 0x09
#define REG_OCP 0x0b
#define REG_LNA 0x0c #define REG_LNA 0x0c
#define REG_FIFO_ADDR_PTR 0x0d #define REG_FIFO_ADDR_PTR 0x0d
#define REG_FIFO_TX_BASE_ADDR 0x0e #define REG_FIFO_TX_BASE_ADDR 0x0e
@ -30,10 +31,13 @@
#define REG_FREQ_ERROR_LSB 0x2a #define REG_FREQ_ERROR_LSB 0x2a
#define REG_RSSI_WIDEBAND 0x2c #define REG_RSSI_WIDEBAND 0x2c
#define REG_DETECTION_OPTIMIZE 0x31 #define REG_DETECTION_OPTIMIZE 0x31
#define REG_INVERTIQ 0x33
#define REG_DETECTION_THRESHOLD 0x37 #define REG_DETECTION_THRESHOLD 0x37
#define REG_SYNC_WORD 0x39 #define REG_SYNC_WORD 0x39
#define REG_INVERTIQ2 0x3b
#define REG_DIO_MAPPING_1 0x40 #define REG_DIO_MAPPING_1 0x40
#define REG_VERSION 0x42 #define REG_VERSION 0x42
#define REG_PA_DAC 0x4d
// modes // modes
#define MODE_LONG_RANGE_MODE 0x80 #define MODE_LONG_RANGE_MODE 0x80
@ -60,7 +64,8 @@
#endif #endif
LoRaClass::LoRaClass() : LoRaClass::LoRaClass() :
_spiSettings(8E6, MSBFIRST, SPI_MODE0), _spiSettings(LORA_DEFAULT_SPI_FREQUENCY, MSBFIRST, SPI_MODE0),
_spi(&LORA_DEFAULT_SPI),
_ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN), _ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN),
_frequency(0), _frequency(0),
_packetIndex(0), _packetIndex(0),
@ -73,6 +78,23 @@ LoRaClass::LoRaClass() :
int LoRaClass::begin(long frequency) int LoRaClass::begin(long frequency)
{ {
#ifdef ARDUINO_SAMD_MKRWAN1300
pinMode(LORA_IRQ_DUMB, OUTPUT);
digitalWrite(LORA_IRQ_DUMB, LOW);
// Hardware reset
pinMode(LORA_BOOT0, OUTPUT);
digitalWrite(LORA_BOOT0, LOW);
pinMode(LORA_RESET, OUTPUT);
digitalWrite(LORA_RESET, HIGH);
delay(200);
digitalWrite(LORA_RESET, LOW);
delay(200);
digitalWrite(LORA_RESET, HIGH);
delay(50);
#endif
// setup pins // setup pins
pinMode(_ss, OUTPUT); pinMode(_ss, OUTPUT);
// set SS high // set SS high
@ -89,7 +111,7 @@ int LoRaClass::begin(long frequency)
} }
// start SPI // start SPI
SPI.begin(); _spi->begin();
// check version // check version
uint8_t version = readRegister(REG_VERSION); uint8_t version = readRegister(REG_VERSION);
@ -128,11 +150,15 @@ void LoRaClass::end()
sleep(); sleep();
// stop SPI // stop SPI
SPI.end(); _spi->end();
} }
int LoRaClass::beginPacket(int implicitHeader) int LoRaClass::beginPacket(int implicitHeader)
{ {
if (isTransmitting()) {
return 0;
}
// put in standby mode // put in standby mode
idle(); idle();
@ -149,22 +175,40 @@ int LoRaClass::beginPacket(int implicitHeader)
return 1; return 1;
} }
int LoRaClass::endPacket() int LoRaClass::endPacket(bool async)
{ {
// put in TX mode // put in TX mode
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX); writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX);
// wait for TX done if (async) {
while ((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0) { // grace time is required for the radio
yield(); delayMicroseconds(150);
} else {
// wait for TX done
while ((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0) {
yield();
}
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
} }
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
return 1; return 1;
} }
bool LoRaClass::isTransmitting()
{
if ((readRegister(REG_OP_MODE) & MODE_TX) == MODE_TX) {
return true;
}
if (readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) {
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
}
return false;
}
int LoRaClass::parsePacket(int size) int LoRaClass::parsePacket(int size)
{ {
int packetLength = 0; int packetLength = 0;
@ -302,6 +346,7 @@ void LoRaClass::flush()
{ {
} }
#ifndef ARDUINO_SAMD_MKRWAN1300
void LoRaClass::onReceive(void(*callback)(int)) void LoRaClass::onReceive(void(*callback)(int))
{ {
_onReceive = callback; _onReceive = callback;
@ -334,6 +379,7 @@ void LoRaClass::receive(int size)
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS); writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS);
} }
#endif
void LoRaClass::idle() void LoRaClass::idle()
{ {
@ -358,10 +404,24 @@ void LoRaClass::setTxPower(int level, int outputPin)
writeRegister(REG_PA_CONFIG, 0x70 | level); writeRegister(REG_PA_CONFIG, 0x70 | level);
} else { } else {
// PA BOOST // PA BOOST
if (level < 2) { if (level > 17) {
level = 2; if (level > 20) {
} else if (level > 17) { level = 20;
level = 17; }
// subtract 3 from level, so 18 - 20 maps to 15 - 17
level -= 3;
// High Power +20 dBm Operation (Semtech SX1276/77/78/79 5.4.3.)
writeRegister(REG_PA_DAC, 0x87);
setOCP(140);
} else {
if (level < 2) {
level = 2;
}
//Default value PA_HF/LF or +17dBm
writeRegister(REG_PA_DAC, 0x84);
setOCP(100);
} }
writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2)); writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2));
@ -379,6 +439,11 @@ void LoRaClass::setFrequency(long frequency)
writeRegister(REG_FRF_LSB, (uint8_t)(frf >> 0)); writeRegister(REG_FRF_LSB, (uint8_t)(frf >> 0));
} }
int LoRaClass::getSpreadingFactor()
{
return readRegister(REG_MODEM_CONFIG_2) >> 4;
}
void LoRaClass::setSpreadingFactor(int sf) void LoRaClass::setSpreadingFactor(int sf)
{ {
if (sf < 6) { if (sf < 6) {
@ -396,23 +461,27 @@ void LoRaClass::setSpreadingFactor(int sf)
} }
writeRegister(REG_MODEM_CONFIG_2, (readRegister(REG_MODEM_CONFIG_2) & 0x0f) | ((sf << 4) & 0xf0)); writeRegister(REG_MODEM_CONFIG_2, (readRegister(REG_MODEM_CONFIG_2) & 0x0f) | ((sf << 4) & 0xf0));
setLdoFlag();
} }
long LoRaClass::getSignalBandwidth() long LoRaClass::getSignalBandwidth()
{ {
byte bw = (readRegister(REG_MODEM_CONFIG_1) >> 4); byte bw = (readRegister(REG_MODEM_CONFIG_1) >> 4);
switch (bw) { switch (bw) {
case 0: return 7.8E3; case 0: return 7.8E3;
case 1: return 10.4E3; case 1: return 10.4E3;
case 2: return 15.6E3; case 2: return 15.6E3;
case 3: return 20.8E3; case 3: return 20.8E3;
case 4: return 31.25E3; case 4: return 31.25E3;
case 5: return 41.7E3; case 5: return 41.7E3;
case 6: return 62.5E3; case 6: return 62.5E3;
case 7: return 125E3; case 7: return 125E3;
case 8: return 250E3; case 8: return 250E3;
case 9: return 500E3; case 9: return 500E3;
} }
return -1;
} }
void LoRaClass::setSignalBandwidth(long sbw) void LoRaClass::setSignalBandwidth(long sbw)
@ -442,6 +511,20 @@ void LoRaClass::setSignalBandwidth(long sbw)
} }
writeRegister(REG_MODEM_CONFIG_1, (readRegister(REG_MODEM_CONFIG_1) & 0x0f) | (bw << 4)); writeRegister(REG_MODEM_CONFIG_1, (readRegister(REG_MODEM_CONFIG_1) & 0x0f) | (bw << 4));
setLdoFlag();
}
void LoRaClass::setLdoFlag()
{
// Section 4.1.1.5
long symbolDuration = 1000 / ( getSignalBandwidth() / (1L << getSpreadingFactor()) ) ;
// Section 4.1.1.6
boolean ldoOn = symbolDuration > 16;
uint8_t config3 = readRegister(REG_MODEM_CONFIG_3);
bitWrite(config3, 3, ldoOn);
writeRegister(REG_MODEM_CONFIG_3, config3);
} }
void LoRaClass::setCodingRate4(int denominator) void LoRaClass::setCodingRate4(int denominator)
@ -478,6 +561,31 @@ void LoRaClass::disableCrc()
writeRegister(REG_MODEM_CONFIG_2, readRegister(REG_MODEM_CONFIG_2) & 0xfb); writeRegister(REG_MODEM_CONFIG_2, readRegister(REG_MODEM_CONFIG_2) & 0xfb);
} }
void LoRaClass::enableInvertIQ()
{
writeRegister(REG_INVERTIQ, 0x66);
writeRegister(REG_INVERTIQ2, 0x19);
}
void LoRaClass::disableInvertIQ()
{
writeRegister(REG_INVERTIQ, 0x27);
writeRegister(REG_INVERTIQ2, 0x1d);
}
void LoRaClass::setOCP(uint8_t mA)
{
uint8_t ocpTrim = 27;
if (mA <= 120) {
ocpTrim = (mA - 45) / 5;
} else if (mA <=240) {
ocpTrim = (mA + 30) / 10;
}
writeRegister(REG_OCP, 0x20 | (0x1F & ocpTrim));
}
byte LoRaClass::random() byte LoRaClass::random()
{ {
return readRegister(REG_RSSI_WIDEBAND); return readRegister(REG_RSSI_WIDEBAND);
@ -490,6 +598,11 @@ void LoRaClass::setPins(int ss, int reset, int dio0)
_dio0 = dio0; _dio0 = dio0;
} }
void LoRaClass::setSPI(SPIClass& spi)
{
_spi = &spi;
}
void LoRaClass::setSPIFrequency(uint32_t frequency) void LoRaClass::setSPIFrequency(uint32_t frequency)
{ {
_spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0); _spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0);
@ -561,10 +674,10 @@ uint8_t LoRaClass::singleTransfer(uint8_t address, uint8_t value)
digitalWrite(_ss, LOW); digitalWrite(_ss, LOW);
SPI.beginTransaction(_spiSettings); _spi->beginTransaction(_spiSettings);
SPI.transfer(address); _spi->transfer(address);
response = SPI.transfer(value); response = _spi->transfer(value);
SPI.endTransaction(); _spi->endTransaction();
digitalWrite(_ss, HIGH); digitalWrite(_ss, HIGH);

View File

@ -7,12 +7,22 @@
#include <Arduino.h> #include <Arduino.h>
#include <SPI.h> #include <SPI.h>
#define LORA_DEFAULT_SS_PIN 10 #ifdef ARDUINO_SAMD_MKRWAN1300
#define LORA_DEFAULT_RESET_PIN 9 #define LORA_DEFAULT_SPI SPI1
#define LORA_DEFAULT_DIO0_PIN 2 #define LORA_DEFAULT_SPI_FREQUENCY 250000
#define LORA_DEFAULT_SS_PIN LORA_IRQ_DUMB
#define LORA_DEFAULT_RESET_PIN -1
#define LORA_DEFAULT_DIO0_PIN -1
#else
#define LORA_DEFAULT_SPI SPI
#define LORA_DEFAULT_SPI_FREQUENCY 8E6
#define LORA_DEFAULT_SS_PIN 10
#define LORA_DEFAULT_RESET_PIN 9
#define LORA_DEFAULT_DIO0_PIN 2
#endif
#define PA_OUTPUT_RFO_PIN 0 #define PA_OUTPUT_RFO_PIN 0
#define PA_OUTPUT_PA_BOOST_PIN 1 #define PA_OUTPUT_PA_BOOST_PIN 1
class LoRaClass : public Stream { class LoRaClass : public Stream {
public: public:
@ -22,7 +32,7 @@ public:
void end(); void end();
int beginPacket(int implicitHeader = false); int beginPacket(int implicitHeader = false);
int endPacket(); int endPacket(bool async = false);
int parsePacket(int size = 0); int parsePacket(int size = 0);
int packetRssi(); int packetRssi();
@ -39,9 +49,11 @@ public:
virtual int peek(); virtual int peek();
virtual void flush(); virtual void flush();
#ifndef ARDUINO_SAMD_MKRWAN1300
void onReceive(void(*callback)(int)); void onReceive(void(*callback)(int));
void receive(int size = 0); void receive(int size = 0);
#endif
void idle(); void idle();
void sleep(); void sleep();
@ -54,6 +66,10 @@ public:
void setSyncWord(int sw); void setSyncWord(int sw);
void enableCrc(); void enableCrc();
void disableCrc(); void disableCrc();
void enableInvertIQ();
void disableInvertIQ();
void setOCP(uint8_t mA); // Over Current Protection control
// deprecated // deprecated
void crc() { enableCrc(); } void crc() { enableCrc(); }
@ -62,6 +78,7 @@ public:
byte random(); byte random();
void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN); void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN);
void setSPI(SPIClass& spi);
void setSPIFrequency(uint32_t frequency); void setSPIFrequency(uint32_t frequency);
void dumpRegisters(Stream& out); void dumpRegisters(Stream& out);
@ -71,9 +88,13 @@ private:
void implicitHeaderMode(); void implicitHeaderMode();
void handleDio0Rise(); void handleDio0Rise();
bool isTransmitting();
int getSpreadingFactor();
long getSignalBandwidth(); long getSignalBandwidth();
void setLdoFlag();
uint8_t readRegister(uint8_t address); uint8_t readRegister(uint8_t address);
void writeRegister(uint8_t address, uint8_t value); void writeRegister(uint8_t address, uint8_t value);
uint8_t singleTransfer(uint8_t address, uint8_t value); uint8_t singleTransfer(uint8_t address, uint8_t value);
@ -82,6 +103,7 @@ private:
private: private:
SPISettings _spiSettings; SPISettings _spiSettings;
SPIClass* _spi;
int _ss; int _ss;
int _reset; int _reset;
int _dio0; int _dio0;