diff --git a/.travis.yml b/.travis.yml index 2dcac81..703d0c7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,5 +28,6 @@ script: - buildExampleSketch LoRaReceiver - buildExampleSketch LoRaReceiverCallback - buildExampleSketch LoRaSender + - buildExampleSketch LoRaSenderNonBlocking - buildExampleSketch LoRaSetSpread - buildExampleSketch LoRaSetSyncWord diff --git a/API.md b/API.md index 07c808e..7fb8c1a 100644 --- a/API.md +++ b/API.md @@ -71,7 +71,7 @@ LoRa.beginPacket(implicitHeader); * `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 @@ -98,8 +98,11 @@ Returns the number of bytes written. End the sequence of sending a packet. ```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. diff --git a/examples/LoRaSenderNonBlocking/LoRaSenderNonBlocking.ino b/examples/LoRaSenderNonBlocking/LoRaSenderNonBlocking.ino new file mode 100644 index 0000000..0f39077 --- /dev/null +++ b/examples/LoRaSenderNonBlocking/LoRaSenderNonBlocking.ino @@ -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++; +} diff --git a/src/LoRa.cpp b/src/LoRa.cpp index 5fb4256..f257887 100644 --- a/src/LoRa.cpp +++ b/src/LoRa.cpp @@ -124,6 +124,10 @@ void LoRaClass::end() int LoRaClass::beginPacket(int implicitHeader) { + if (isTransmitting()) { + return 0; + } + // put in standby mode idle(); @@ -140,22 +144,40 @@ int LoRaClass::beginPacket(int implicitHeader) return 1; } -int LoRaClass::endPacket() +int LoRaClass::endPacket(bool async) { // put in TX mode writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX); - // wait for TX done - while ((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0) { - yield(); + if (async) { + // grace time is required for the radio + 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; } +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 packetLength = 0; diff --git a/src/LoRa.h b/src/LoRa.h index 7616ebd..a51b47d 100644 --- a/src/LoRa.h +++ b/src/LoRa.h @@ -22,7 +22,7 @@ class LoRaClass : public Stream { void end(); int beginPacket(int implicitHeader = false); - int endPacket(); + int endPacket(bool async = false); int parsePacket(int size = 0); int packetRssi(); @@ -70,6 +70,7 @@ class LoRaClass : public Stream { void implicitHeaderMode(); void handleDio0Rise(); + bool isTransmitting(); uint8_t readRegister(uint8_t address); void writeRegister(uint8_t address, uint8_t value);