diff --git a/API.md b/API.md index 5f7563e..22afc67 100644 --- a/API.md +++ b/API.md @@ -24,10 +24,11 @@ Returns `1` on success, `0` on failure. Override the default `NSS` and `NRESET` pins used by the library. **Must** be called before `LoRa.begin()`. ```arduino -LoRa.setPins(ss, reset); +LoRa.setPins(ss, reset, dio0); ``` * `ss` new slave select pin to use, defaults to `10` * `reset` new reset pin to use, defaults to `9` + * `dio0` new DIO0 pin to use, defaults to `2` ### End diff --git a/README.md b/README.md index a3c98c3..55329a8 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,10 @@ An [Arduino](http://arduino.cc/) library for sending and receiving data using [L | MOSI | MOSI | | NSS | 10 | | NRESET | 9 | +| DIO0 | 2 | -`NSS` and `NRESET` pins can be changed by using `LoRa.setPins(ss, reset)`. +`NSS`, `NRESET`, and `DIO0` pins can be changed by using `LoRa.setPins(ss, reset, dio0)`. `DIO0` pin is optional, it is only needed for receive callback mode. ## Installation diff --git a/examples/LoRaReceiverCallback/LoRaReceiverCallback.ino b/examples/LoRaReceiverCallback/LoRaReceiverCallback.ino new file mode 100644 index 0000000..1920c5d --- /dev/null +++ b/examples/LoRaReceiverCallback/LoRaReceiverCallback.ino @@ -0,0 +1,39 @@ +#include +#include + +void setup() { + Serial.begin(9600); + while (!Serial); + + Serial.println("LoRa Receiver Callback"); + + if (!LoRa.begin(915E6)) { + Serial.println("Starting LoRa failed!"); + while (1); + } + + // register the receive callback + LoRa.onReceive(onReceive); + + // put the radio into receive mode + LoRa.receive(); +} + +void loop() { + // do nothing +} + +void onReceive(int packetSize) { + // received a packet + Serial.print("Received packet '"); + + // read packet + for (int i = 0; i < packetSize; i++) { + Serial.print((char)LoRa.read()); + } + + // print RSSI of packet + Serial.print("' with RSSI "); + Serial.println(LoRa.packetRssi()); +} + diff --git a/keywords.txt b/keywords.txt index 29c8e92..a77c92f 100644 --- a/keywords.txt +++ b/keywords.txt @@ -28,6 +28,11 @@ read KEYWORD2 peek KEYWORD2 flush KEYWORD2 +onReceive KEYWORD2 +receive KEYWORD2 +idle KEYWORD2 +sleep KEYWORD2 + setPins KEYWORD2 dumpRegisters KEYWORD2 diff --git a/src/LoRa.cpp b/src/LoRa.cpp index 2961385..5711e62 100644 --- a/src/LoRa.cpp +++ b/src/LoRa.cpp @@ -15,6 +15,7 @@ #define REG_RX_NB_BYTES 0x13 #define REG_PKT_RSSI_VALUE 0x1a #define REG_PAYLOAD_LENGTH 0x22 +#define REG_DIO_MAPPING_1 0x40 #define REG_VERSION 0x42 // modes @@ -22,6 +23,7 @@ #define MODE_SLEEP 0x00 #define MODE_STDBY 0x01 #define MODE_TX 0x03 +#define MODE_RX_CONTINUOUS 0x05 #define MODE_RX_SINGLE 0x06 // PA config @@ -35,9 +37,10 @@ LoRaClass::LoRaClass() : _spiSettings(10E6, MSBFIRST, SPI_MODE0), - _ss(10), _reset(9), + _ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN), _frequency(0), - _packetIndex(0) + _packetIndex(0), + _onReceive(NULL) { } @@ -225,10 +228,39 @@ void LoRaClass::flush() { } -void LoRaClass::setPins(int ss, int reset) +void LoRaClass::onReceive(void(*callback)(int)) +{ + _onReceive = callback; + + if (callback) { + writeRegister(REG_DIO_MAPPING_1, 0x00); + + attachInterrupt(digitalPinToInterrupt(_dio0), LoRaClass::onDio0Rise, RISING); + } else { + detachInterrupt(digitalPinToInterrupt(_dio0)); + } +} + +void LoRaClass::receive() +{ + writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS); +} + +void LoRaClass::idle() +{ + writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY); +} + +void LoRaClass::sleep() +{ + writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP); +} + +void LoRaClass::setPins(int ss, int reset, int dio0) { _ss = ss; _reset = reset; + _dio0 = dio0; } void LoRaClass::dumpRegisters(Stream& out) @@ -241,6 +273,30 @@ void LoRaClass::dumpRegisters(Stream& out) } } +void LoRaClass::handleDio0Rise() +{ + int irqFlags = readRegister(REG_IRQ_FLAGS); + + // clear IRQ's + writeRegister(REG_IRQ_FLAGS, irqFlags); + + // received a packet + _packetIndex = 0; + + // read packet length + int packetLength = readRegister(REG_RX_NB_BYTES); + + // 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); +} + uint8_t LoRaClass::readRegister(uint8_t address) { return singleTransfer(address & 0x7f, 0x00); @@ -267,4 +323,9 @@ uint8_t LoRaClass::singleTransfer(uint8_t address, uint8_t value) return response; } +void LoRaClass::onDio0Rise() +{ + LoRa.handleDio0Rise(); +} + LoRaClass LoRa; diff --git a/src/LoRa.h b/src/LoRa.h index f161faa..018f5eb 100644 --- a/src/LoRa.h +++ b/src/LoRa.h @@ -4,6 +4,10 @@ #include #include +#define LORA_DEFAULT_SS_PIN 10 +#define LORA_DEFAULT_RESET_PIN 9 +#define LORA_DEFAULT_DIO0_PIN 2 + class LoRaClass : public Stream { public: LoRaClass(); @@ -27,21 +31,33 @@ public: virtual int peek(); virtual void flush(); - void setPins(int ss, int reset); + void onReceive(void(*callback)(int)); + + void receive(); + void idle(); + void sleep(); + + void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN); void dumpRegisters(Stream& out); private: + void handleDio0Rise(); + uint8_t readRegister(uint8_t address); void writeRegister(uint8_t address, uint8_t value); uint8_t singleTransfer(uint8_t address, uint8_t value); + static void onDio0Rise(); + private: SPISettings _spiSettings; int _ss; int _reset; + int _dio0; int _frequency; int _packetIndex; + void (*_onReceive)(int); }; extern LoRaClass LoRa;