Skip to content

Commit 16728e9

Browse files
committed
Add SX127x TX and RX operation using interrupt
1 parent a95bf42 commit 16728e9

File tree

2 files changed

+90
-11
lines changed

2 files changed

+90
-11
lines changed

src/SX127x.cpp

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ uint32_t SX127x::_spiFrequency = SX127X_SPI_FREQUENCY;
66

77
int8_t SX127x::_nssStatic = SX127X_PIN_NSS;
88

9-
uint8_t SX127x::_statusIrq = 0x00;
9+
uint8_t SX127x::_statusIrq = 0xFF;
1010

1111
uint32_t SX127x::_transmitTime = 0;
1212

1313
uint8_t SX127x::_payloadTxRx = 0;
1414

15+
int8_t SX127x::_irqStatic = -1;
16+
1517
int8_t SX127x::_pinToLow = -1;
1618

1719
SX127x::SX127x()
@@ -109,6 +111,7 @@ void SX127x::setPins(int8_t nss, int8_t reset, int8_t irq, int8_t txen, int8_t r
109111
_irq = irq;
110112
_txen = txen;
111113
_rxen = rxen;
114+
_irqStatic = digitalPinToInterrupt(_irq);
112115
}
113116

114117
void SX127x::setCurrentProtection(uint8_t current)
@@ -319,7 +322,7 @@ void SX127x::beginPacket()
319322
}
320323
}
321324

322-
void SX127x::endPacket()
325+
void SX127x::endPacket(bool intFlag)
323326
{
324327
// set packet payload length
325328
writeRegister(SX127X_REG_PAYLOAD_LENGTH, _payloadTxRx);
@@ -332,6 +335,11 @@ void SX127x::endPacket()
332335
writeRegister(SX127X_REG_OP_MODE, _modem | SX127X_MODE_TX);
333336
_transmitTime = millis();
334337

338+
// set TX done interrupt on DIO0 and attach TX interrupt handler
339+
if (_irq != -1 && intFlag) {
340+
writeRegister(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_TX_DONE);
341+
attachInterrupt(_irqStatic, SX127x::_interruptTx, RISING);
342+
}
335343
}
336344

337345
void SX127x::write(uint8_t data)
@@ -357,7 +365,7 @@ void SX127x::write(char* data, uint8_t length)
357365
write(data_, length);
358366
}
359367

360-
void SX127x::request(uint32_t timeout)
368+
void SX127x::request(uint32_t timeout, bool intFlag)
361369
{
362370
// clear IRQ flag from last TX or RX operation
363371
writeRegister(SX127X_REG_IRQ_FLAGS, 0xFF);
@@ -388,6 +396,16 @@ void SX127x::request(uint32_t timeout)
388396

389397
// set device to receive mode
390398
writeRegister(SX127X_REG_OP_MODE, _modem | rxMode);
399+
400+
// set RX done interrupt on DIO0 and attach RX interrupt handler
401+
if (_irq != -1 && intFlag) {
402+
writeRegister(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_RX_DONE);
403+
if (timeout == SX127X_RX_CONTINUOUS) {
404+
attachInterrupt(_irqStatic, SX127x::_interruptRxContinuous, RISING);
405+
} else {
406+
attachInterrupt(_irqStatic, SX127x::_interruptRx, RISING);
407+
}
408+
}
391409
}
392410

393411
uint8_t SX127x::available()
@@ -439,20 +457,30 @@ bool SX127x::wait(uint32_t timeout)
439457
// immediately return when currently not waiting transmit or receive process
440458
if (_statusIrq) return false;
441459

460+
#ifdef SPI_HAS_NOTUSINGINTERRUPT
461+
_spi->usingInterrupt(_irqStatic);
462+
#endif
442463
// wait transmit or receive process finish by checking IRQ status
443464
uint8_t irqFlag = 0x00;
444465
uint8_t irqFlagMask = _statusWait == SX127X_STATUS_TX_WAIT
445466
? SX127X_IRQ_TX_DONE
446467
: SX127X_IRQ_RX_DONE | SX127X_IRQ_RX_TIMEOUT | SX127X_IRQ_CRC_ERR
447468
;
448469
uint32_t t = millis();
449-
while (!(irqFlag & irqFlagMask)) {
470+
while (!(irqFlag & irqFlagMask) && _statusIrq == 0x00) {
450471
irqFlag = readRegister(SX127X_REG_IRQ_FLAGS);
451472
// return when timeout reached
452473
if (millis() - t > timeout && timeout != 0) return false;
453474
}
475+
#ifdef SPI_HAS_NOTUSINGINTERRUPT
476+
_spi->notUsingInterrupt(_irqStatic);
477+
#endif
478+
479+
if (_statusIrq) {
480+
// immediately return when interrupt signal hit
481+
return false;
454482

455-
if (_statusWait == SX127X_STATUS_TX_WAIT) {
483+
} else if (_statusWait == SX127X_STATUS_TX_WAIT) {
456484
// calculate transmit time and set back txen pin to low
457485
_transmitTime = millis() - _transmitTime;
458486
if (_txen != -1) digitalWrite(_txen, LOW);
@@ -489,7 +517,6 @@ uint8_t SX127x::status()
489517

490518
// get status for transmit and receive operation based on status IRQ
491519
if (statusIrq & SX127X_IRQ_RX_TIMEOUT) return SX127X_STATUS_RX_TIMEOUT;
492-
else if (!(statusIrq & SX127X_IRQ_HEADER_VALID)) return SX127X_STATUS_HEADER_ERR;
493520
else if (statusIrq & SX127X_IRQ_CRC_ERR) return SX127X_STATUS_CRC_ERR;
494521
else if (statusIrq & SX127X_IRQ_TX_DONE) return SX127X_STATUS_TX_DONE;
495522
else if (statusIrq & SX127X_IRQ_RX_DONE) return SX127X_STATUS_RX_DONE;
@@ -535,6 +562,53 @@ float SX127x::snr()
535562
return readRegister(SX127X_REG_PKT_SNR_VALUE) / 4.0;
536563
}
537564

565+
void SX127x::_interruptTx()
566+
{
567+
// calculate transmit time
568+
_transmitTime = millis() - _transmitTime;
569+
570+
// store IRQ status as TX done
571+
_statusIrq = SX127X_IRQ_TX_DONE;
572+
573+
// set back txen pin to low and detach interrupt
574+
if (_pinToLow != -1) digitalWrite(_pinToLow, LOW);
575+
detachInterrupt(_irqStatic);
576+
}
577+
578+
void SX127x::_interruptRx()
579+
{
580+
// store IRQ status
581+
_statusIrq = readRegister(SX127X_REG_IRQ_FLAGS);
582+
// set IRQ status to RX done when interrupt occured before register updated
583+
if (!(_statusIrq & 0xF0)) _statusIrq = SX127X_IRQ_RX_DONE;
584+
585+
// terminate receive mode by setting mode to standby
586+
writeBits(SX127X_REG_OP_MODE, SX127X_MODE_STDBY, 0, 3);
587+
588+
// set back rxen pin to low and detach interrupt
589+
if (_pinToLow != -1) digitalWrite(_pinToLow, LOW);
590+
detachInterrupt(_irqStatic);
591+
592+
// set pointer to RX buffer base address and get packet payload length
593+
writeRegister(SX127X_REG_FIFO_ADDR_PTR, readRegister(SX127X_REG_FIFO_RX_CURRENT_ADDR));
594+
_payloadTxRx = readRegister(SX127X_REG_RX_NB_BYTES);
595+
}
596+
597+
void SX127x::_interruptRxContinuous()
598+
{
599+
// store IRQ status
600+
_statusIrq = readRegister(SX127X_REG_IRQ_FLAGS);
601+
// set IRQ status to RX done when interrupt occured before register updated
602+
if (!(_statusIrq & 0xF0)) _statusIrq = SX127X_IRQ_RX_DONE;
603+
604+
// clear IRQ flag from last TX or RX operation
605+
writeRegister(SX127X_REG_IRQ_FLAGS, 0xFF);
606+
607+
// set pointer to RX buffer base address and get packet payload length
608+
writeRegister(SX127X_REG_FIFO_ADDR_PTR, readRegister(SX127X_REG_FIFO_RX_CURRENT_ADDR));
609+
_payloadTxRx = readRegister(SX127X_REG_RX_NB_BYTES);
610+
}
611+
538612
void SX127x::writeBits(uint8_t address, uint8_t data, uint8_t position, uint8_t length)
539613
{
540614
uint8_t read = _transfer(address & 0x7F, 0x00);

src/SX127x.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@
7878
#define SX127x_OSC_CRYSTAL 0x00 // crystal oscillator with external crystal
7979
#define SX127X_OSC_TCXO 0x10 // external clipped sine TCXO AC-connected to XTA pin
8080

81+
// DIO mapping
82+
#define SX127X_DIO0_RX_DONE 0x00 // set DIO0 interrupt for: RX done
83+
#define SX127X_DIO0_TX_DONE 0x40 // TX done
84+
#define SX127X_DIO0_CAD_DONE 0x80 // CAD done
85+
8186
// IRQ flags
8287
#define SX127X_IRQ_CAD_DETECTED 0x01 // Valid Lora signal detected during CAD operation
8388
#define SX127X_IRQ_FHSS_CHANGE 0x02 // FHSS change channel interrupt
@@ -108,9 +113,6 @@
108113
#define SX127X_STATUS_CAD_WAIT LORA_STATUS_CAD_WAIT
109114
#define SX127X_STATUS_CAD_DETECTED LORA_STATUS_CAD_DETECTED
110115
#define SX127X_STATUS_CAD_DONE LORA_STATUS_CAD_DONE
111-
#define SX126X_STATUS_INT_WAIT LORA_STATUS_INT_WAIT
112-
#define SX126X_STATUS_INT_TX LORA_STATUS_INT_TX
113-
#define SX126X_STATUS_INT_RX LORA_STATUS_INT_RX
114116

115117
// Default Hardware Configuration
116118
#define SX127X_PIN_NSS 10
@@ -164,7 +166,7 @@ class SX127x : public BaseLoRa
164166

165167
// Transmit related methods
166168
void beginPacket();
167-
void endPacket();
169+
void endPacket(bool intFlag=true);
168170
void write(uint8_t data);
169171
void write(uint8_t* data, uint8_t length);
170172
void write(char* data, uint8_t length);
@@ -181,7 +183,7 @@ class SX127x : public BaseLoRa
181183
}
182184

183185
// Receive related methods
184-
void request(uint32_t timeout=SX127X_RX_SINGLE);
186+
void request(uint32_t timeout=SX127X_RX_SINGLE, bool intFlag=true);
185187
uint8_t available();
186188
uint8_t read();
187189
uint8_t read(uint8_t* data, uint8_t length);
@@ -237,6 +239,9 @@ class SX127x : public BaseLoRa
237239
static int8_t _irqStatic;
238240
static int8_t _pinToLow;
239241

242+
static void _interruptTx();
243+
static void _interruptRx();
244+
static void _interruptRxContinuous();
240245
static uint8_t _transfer(uint8_t address, uint8_t data);
241246

242247
};

0 commit comments

Comments
 (0)