From e6415185109734c3e77addae82ae3f9ef1929a26 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Mon, 13 Jan 2020 19:01:39 -0300 Subject: [PATCH 1/4] OnTxDone Add callback onTxDone --- API.md | 18 ++++++++++++++++ keywords.txt | 1 + src/LoRa.cpp | 60 ++++++++++++++++++++++++++++++++++++++++------------ src/LoRa.h | 2 ++ 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/API.md b/API.md index ded3b9c..0f952ef 100644 --- a/API.md +++ b/API.md @@ -117,6 +117,24 @@ LoRa.endPacket(async); Returns `1` on success, `0` on failure. +### Tx Done + +**WARNING**: Not supported on the Arduino MKR WAN 1300 board! + +### Register callback + +Register a callback function for when a packet transmission finish. + +```arduino +LoRa.onTxDone(onTxDone); + +void onTxDone() { + // ... +} +``` + + * `onTxDone` - function to call when a packet transmission finish. + ## Receiving data ### Parsing packet diff --git a/keywords.txt b/keywords.txt index 2cf0351..63e0e9a 100644 --- a/keywords.txt +++ b/keywords.txt @@ -31,6 +31,7 @@ peek KEYWORD2 flush KEYWORD2 onReceive KEYWORD2 +onTxDone KEYWORD2 receive KEYWORD2 idle KEYWORD2 sleep KEYWORD2 diff --git a/src/LoRa.cpp b/src/LoRa.cpp index aef149c..6980f5a 100644 --- a/src/LoRa.cpp +++ b/src/LoRa.cpp @@ -70,7 +70,8 @@ LoRaClass::LoRaClass() : _frequency(0), _packetIndex(0), _implicitHeaderMode(0), - _onReceive(NULL) + _onReceive(NULL), + _onTxDone(NULL) { // overide Stream timeout value setTimeout(0); @@ -177,13 +178,14 @@ int LoRaClass::beginPacket(int implicitHeader) int LoRaClass::endPacket(bool async) { + + if ((async) && (_onTxDone)) + writeRegister(REG_DIO_MAPPING_1, 0x40); // DIO0 => TXDONE + // put in TX mode writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX); - if (async) { - // grace time is required for the radio - delayMicroseconds(150); - } else { + if (!async) { // wait for TX done while ((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0) { yield(); @@ -353,8 +355,24 @@ void LoRaClass::onReceive(void(*callback)(int)) if (callback) { pinMode(_dio0, INPUT); +#ifdef SPI_HAS_NOTUSINGINTERRUPT + SPI.usingInterrupt(digitalPinToInterrupt(_dio0)); +#endif + attachInterrupt(digitalPinToInterrupt(_dio0), LoRaClass::onDio0Rise, RISING); + } else { + detachInterrupt(digitalPinToInterrupt(_dio0)); +#ifdef SPI_HAS_NOTUSINGINTERRUPT + SPI.notUsingInterrupt(digitalPinToInterrupt(_dio0)); +#endif + } +} - writeRegister(REG_DIO_MAPPING_1, 0x00); +void LoRaClass::onTxDone(void(*callback)()) +{ + _onTxDone = callback; + + if (callback) { + pinMode(_dio0, INPUT); #ifdef SPI_HAS_NOTUSINGINTERRUPT SPI.usingInterrupt(digitalPinToInterrupt(_dio0)); #endif @@ -369,6 +387,9 @@ void LoRaClass::onReceive(void(*callback)(int)) void LoRaClass::receive(int size) { + + writeRegister(REG_DIO_MAPPING_1, 0x00); // DIO0 => RXDONE + if (size > 0) { implicitHeaderMode(); @@ -640,17 +661,28 @@ void LoRaClass::handleDio0Rise() writeRegister(REG_IRQ_FLAGS, irqFlags); if ((irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0) { - // received a packet - _packetIndex = 0; - // read packet length - int packetLength = _implicitHeaderMode ? readRegister(REG_PAYLOAD_LENGTH) : readRegister(REG_RX_NB_BYTES); + if ((irqFlags & IRQ_RX_DONE_MASK) != 0) { + // received a packet + _packetIndex = 0; - // set FIFO address to current RX address - writeRegister(REG_FIFO_ADDR_PTR, readRegister(REG_FIFO_RX_CURRENT_ADDR)); + // read packet length + int packetLength = _implicitHeaderMode ? readRegister(REG_PAYLOAD_LENGTH) : readRegister(REG_RX_NB_BYTES); - if (_onReceive) { - _onReceive(packetLength); + // set FIFO address to current RX address + writeRegister(REG_FIFO_ADDR_PTR, readRegister(REG_FIFO_RX_CURRENT_ADDR)); + + if (_onReceive) { + _onReceive(packetLength); + } + + // reset FIFO address + writeRegister(REG_FIFO_ADDR_PTR, 0); + } + else if ((irqFlags & IRQ_TX_DONE_MASK) != 0) { + if (_onTxDone) { + _onTxDone(); + } } } } diff --git a/src/LoRa.h b/src/LoRa.h index 294f537..c1671c1 100644 --- a/src/LoRa.h +++ b/src/LoRa.h @@ -57,6 +57,7 @@ public: #ifndef ARDUINO_SAMD_MKRWAN1300 void onReceive(void(*callback)(int)); + void onTxDone(void(*callback)()); void receive(int size = 0); #endif @@ -117,6 +118,7 @@ private: int _packetIndex; int _implicitHeaderMode; void (*_onReceive)(int); + void (*_onTxDone)(); }; extern LoRaClass LoRa; From d0ee20860faea5cd7ebebd61a357896a8dc89931 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Mon, 13 Jan 2020 19:17:41 -0300 Subject: [PATCH 2/4] Create LoRaSenderNonBlockingCallback.ino Simple Example non-blocking callback --- .../LoRaSenderNonBlockingCallback.ino | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 examples/LoRaSenderNonBlockingCallback/LoRaSenderNonBlockingCallback.ino diff --git a/examples/LoRaSenderNonBlockingCallback/LoRaSenderNonBlockingCallback.ino b/examples/LoRaSenderNonBlockingCallback/LoRaSenderNonBlockingCallback.ino new file mode 100644 index 0000000..88e5e2f --- /dev/null +++ b/examples/LoRaSenderNonBlockingCallback/LoRaSenderNonBlockingCallback.ino @@ -0,0 +1,50 @@ +#include +#include + +int counter = 0; + +void setup() { + Serial.begin(9600); + while (!Serial); + + Serial.println("LoRa Sender non-blocking Callback"); + + if (!LoRa.begin(915E6)) { + Serial.println("Starting LoRa failed!"); + while (1); + } + + LoRa.onTxDone(onTxDone); +} + +void loop() { + if (runEvery(1000)) { // repeat every 1000 millis + + 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++; + } +} + +void onTxDone() { + Serial.println("TxDone"); +} + +boolean runEvery(unsigned long interval) +{ + static unsigned long previousMillis = 0; + unsigned long currentMillis = millis(); + if (currentMillis - previousMillis >= interval) + { + previousMillis = currentMillis; + return true; + } + return false; +} From 1095e4ebb151d8b8478f500a44dfdf0d35cc6f1a Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Mon, 13 Jan 2020 19:32:57 -0300 Subject: [PATCH 3/4] Update Example Update SimpleNode and SimpleGateway --- examples/LoRaSimpleGateway/LoRaSimpleGateway.ino | 8 ++++++-- examples/LoRaSimpleNode/LoRaSimpleNode.ino | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino b/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino index 745bf1f..95d84a7 100644 --- a/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino +++ b/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino @@ -53,6 +53,7 @@ void setup() { Serial.println(); LoRa.onReceive(onReceive); + LoRa.onTxDone(onTxDone); LoRa_rxMode(); } @@ -83,8 +84,7 @@ 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 + LoRa.endPacket(true); // finish packet and send it } void onReceive(int packetSize) { @@ -96,7 +96,11 @@ void onReceive(int packetSize) { Serial.print("Gateway Receive: "); Serial.println(message); +} +void onTxDone() { + Serial.println("TxDone"); + LoRa_rxMode(); } boolean runEvery(unsigned long interval) diff --git a/examples/LoRaSimpleNode/LoRaSimpleNode.ino b/examples/LoRaSimpleNode/LoRaSimpleNode.ino index a6cb0c0..db8c6fa 100644 --- a/examples/LoRaSimpleNode/LoRaSimpleNode.ino +++ b/examples/LoRaSimpleNode/LoRaSimpleNode.ino @@ -53,6 +53,7 @@ void setup() { Serial.println(); LoRa.onReceive(onReceive); + LoRa.onTxDone(onTxDone); LoRa_rxMode(); } @@ -83,8 +84,7 @@ 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 + LoRa.endPacket(true); // finish packet and send it } void onReceive(int packetSize) { @@ -96,7 +96,11 @@ void onReceive(int packetSize) { Serial.print("Node Receive: "); Serial.println(message); +} +void onTxDone() { + Serial.println("TxDone"); + LoRa_rxMode(); } boolean runEvery(unsigned long interval) From 4eefce887afa97de4d67471dbbba239fc4c4b910 Mon Sep 17 00:00:00 2001 From: Luiz Henrique Cassettari Date: Thu, 23 Jan 2020 09:46:50 -0300 Subject: [PATCH 4/4] Update API.md Remove this warning Add dio0 interrupt callbacks --- API.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/API.md b/API.md index 0f952ef..78f054d 100644 --- a/API.md +++ b/API.md @@ -38,6 +38,10 @@ 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 +#### Pin dio0 interrupt callbacks + +The dio0 pin can be used for transmission finish callback and/or receiving callback, check `onTxDone` and `onReceive`. + ### Set SPI interface Override the default SPI interface used by the library. **Must** be called before `LoRa.begin()`. @@ -119,7 +123,7 @@ Returns `1` on success, `0` on failure. ### Tx Done -**WARNING**: Not supported on the Arduino MKR WAN 1300 board! +**WARNING**: TxDone callback uses the interrupt pin on the `dio0` check `setPins` function! ### Register callback @@ -154,7 +158,7 @@ Returns the packet size in bytes or `0` if no packet was received. ### Continuous receive mode -**WARNING**: Not supported on the Arduino MKR WAN 1300 board! +**WARNING**: Receive callback uses the interrupt pin on the `dio0`, check `setPins` function! #### Register callback