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;