Skip to content

Commit d8a2c0a

Browse files
author
Minoru Tomobe
committed
Add Channel Activity Detection avility.
1 parent 26640bc commit d8a2c0a

File tree

5 files changed

+120
-5
lines changed

5 files changed

+120
-5
lines changed

API.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ To save further pins one could connect the reset pin of the MCU with reset pin o
4040

4141
#### Pin dio0 interrupt callbacks
4242

43-
The dio0 pin can be used for transmission finish callback and/or receiving callback, check `onTxDone` and `onReceive`.
43+
The dio0 pin can be used for channel activity detection callback, transmission finish callback and/or receiving callback, check `onCadDone` , `onTxDone`, and `onReceive`.
4444

4545
### Set SPI interface
4646

@@ -242,6 +242,27 @@ Returns the next byte in the packet or `-1` if no bytes are available.
242242

243243
**Note:** Other Arduino [`Stream` API's](https://www.arduino.cc/en/Reference/Stream) can also be used to read data from the packet
244244

245+
## Channel Activity Detection
246+
**WARNING**: Channel activity detection callback uses the interrupt pin on the `dio0`, check `setPins` function!
247+
248+
### Register callback
249+
250+
Register a callback function for when channel activity detection has done.
251+
```arduino
252+
LoRa.onCadDone(onCadDone);
253+
254+
void onCadDone(boolean signalDetected) {
255+
// ...
256+
}
257+
```
258+
* `onCadDone` - function to call when channel activity detection has done.
259+
* `signalDetected` - if `true`, the radio detects the presence of other LoRa signals.
260+
261+
### Channel Activity detection mode
262+
Puts the radio in channel activity detection mode.
263+
```arduino
264+
LoRa.CAD();
265+
```
245266
## Other radio modes
246267

247268
### Idle mode
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <SPI.h>
2+
#include "LoRa.h"
3+
4+
#ifdef ARDUINO_SAMD_MKRWAN1300
5+
#error "This example is not compatible with the Arduino MKR WAN 1300 board!"
6+
#endif
7+
8+
void setup() {
9+
Serial.begin(9600);
10+
while (!Serial);
11+
12+
Serial.println("LoRa Receiver Callback");
13+
14+
if (!LoRa.begin(915E6)) {
15+
Serial.println("Starting LoRa failed!");
16+
while (1);
17+
}
18+
19+
// register the channel activity dectection callback
20+
LoRa.onCadDone(onCadDone);
21+
// register the receive callback
22+
LoRa.onReceive(onReceive);
23+
// put the radio into CAD mode
24+
LoRa.CAD();
25+
}
26+
27+
void loop() {
28+
// do nothing
29+
}
30+
31+
void onCadDone(boolean signalDetected) {
32+
// detect preamble
33+
if (signalDetected) {
34+
Serial.println("Signal detected");
35+
// put the radio into continuous receive mode
36+
LoRa.receive();
37+
} else {
38+
// try next activity dectection
39+
LoRa.CAD();
40+
}
41+
}
42+
43+
void onReceive(int packetSize) {
44+
// received a packet
45+
Serial.print("Received packet '");
46+
47+
// read packet
48+
for (int i = 0; i < packetSize; i++) {
49+
Serial.print((char)LoRa.read());
50+
}
51+
52+
// print RSSI of packet
53+
Serial.print("' with RSSI ");
54+
Serial.println(LoRa.packetRssi());
55+
56+
// put the radio into CAD mode
57+
LoRa.CAD();
58+
}

keywords.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ flush KEYWORD2
3232

3333
onReceive KEYWORD2
3434
onTxDone KEYWORD2
35+
onCadDone KEYWORD2
36+
CAD KEYWORD2
3537
receive KEYWORD2
3638
idle KEYWORD2
3739
sleep KEYWORD2

src/LoRa.cpp

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#define MODE_TX 0x03
4747
#define MODE_RX_CONTINUOUS 0x05
4848
#define MODE_RX_SINGLE 0x06
49+
#define MODE_CAD 0x07
4950

5051
// PA config
5152
#define PA_BOOST 0x80
@@ -54,6 +55,8 @@
5455
#define IRQ_TX_DONE_MASK 0x08
5556
#define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
5657
#define IRQ_RX_DONE_MASK 0x40
58+
#define IRQ_CAD_DONE_MASK 0x04
59+
#define IRQ_CAD_DETECTED_MASK 0x01
5760

5861
#define MAX_PKT_LENGTH 255
5962

@@ -71,6 +74,7 @@ LoRaClass::LoRaClass() :
7174
_packetIndex(0),
7275
_implicitHeaderMode(0),
7376
_onReceive(NULL),
77+
_onCadDone(NULL),
7478
_onTxDone(NULL)
7579
{
7680
// overide Stream timeout value
@@ -199,7 +203,7 @@ int LoRaClass::endPacket(bool async)
199203

200204
bool LoRaClass::isTransmitting()
201205
{
202-
if ((readRegister(REG_OP_MODE) & MODE_TX) == MODE_TX) {
206+
if ((readRegister(REG_OP_MODE) & B111) == MODE_TX) {
203207
return true;
204208
}
205209

@@ -367,6 +371,24 @@ void LoRaClass::onReceive(void(*callback)(int))
367371
}
368372
}
369373

374+
void LoRaClass::onCadDone(void(*callback)(boolean))
375+
{
376+
_onCadDone = callback;
377+
378+
if (callback) {
379+
pinMode(_dio0, INPUT);
380+
#ifdef SPI_HAS_NOTUSINGINTERRUPT
381+
SPI.usingInterrupt(digitalPinToInterrupt(_dio0));
382+
#endif
383+
attachInterrupt(digitalPinToInterrupt(_dio0), LoRaClass::onDio0Rise, RISING);
384+
} else {
385+
detachInterrupt(digitalPinToInterrupt(_dio0));
386+
#ifdef SPI_HAS_NOTUSINGINTERRUPT
387+
SPI.notUsingInterrupt(digitalPinToInterrupt(_dio0));
388+
#endif
389+
}
390+
}
391+
370392
void LoRaClass::onTxDone(void(*callback)())
371393
{
372394
_onTxDone = callback;
@@ -400,6 +422,12 @@ void LoRaClass::receive(int size)
400422

401423
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS);
402424
}
425+
426+
void LoRaClass::CAD(void)
427+
{
428+
writeRegister(REG_DIO_MAPPING_1, 0x80);// DIO0 => CADDONE
429+
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_CAD);
430+
}
403431
#endif
404432

405433
void LoRaClass::idle()
@@ -660,7 +688,11 @@ void LoRaClass::handleDio0Rise()
660688
// clear IRQ's
661689
writeRegister(REG_IRQ_FLAGS, irqFlags);
662690

663-
if ((irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0) {
691+
if ((irqFlags & IRQ_CAD_DONE_MASK) != 0) {
692+
if (_onCadDone) {
693+
_onCadDone((irqFlags & IRQ_CAD_DETECTED_MASK) != 0);
694+
}
695+
} else if ((irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0) {
664696

665697
if ((irqFlags & IRQ_RX_DONE_MASK) != 0) {
666698
// received a packet
@@ -678,8 +710,7 @@ void LoRaClass::handleDio0Rise()
678710

679711
// reset FIFO address
680712
writeRegister(REG_FIFO_ADDR_PTR, 0);
681-
}
682-
else if ((irqFlags & IRQ_TX_DONE_MASK) != 0) {
713+
} else if ((irqFlags & IRQ_TX_DONE_MASK) != 0) {
683714
if (_onTxDone) {
684715
_onTxDone();
685716
}

src/LoRa.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@ class LoRaClass : public Stream {
5757

5858
#ifndef ARDUINO_SAMD_MKRWAN1300
5959
void onReceive(void(*callback)(int));
60+
void onCadDone(void(*callback)(boolean));
6061
void onTxDone(void(*callback)());
6162

6263
void receive(int size = 0);
64+
void CAD(void);
6365
#endif
6466
void idle();
6567
void sleep();
@@ -118,6 +120,7 @@ class LoRaClass : public Stream {
118120
int _packetIndex;
119121
int _implicitHeaderMode;
120122
void (*_onReceive)(int);
123+
void (*_onCadDone)(boolean);
121124
void (*_onTxDone)();
122125
};
123126

0 commit comments

Comments
 (0)