It seems no detection is done, and “confirmed uplinks” might be needed to tell if data was received. (But the number of confirmed uplinks is limited too.)
As my conclusion is solely based on browsing documentation and code, some background below.
For plain LoRa, the Semtech SX127x datasheet shows that collision detection is available while receiving, but no word about transmitting.
For transmitting, given the following operating modes:
- […]
- STANDBY: Both Crystal oscillator and LoRa baseband blocks are turned on. RF part and PLLs are disabled.
- TX: When activated the SX1276/77/78/79 powers all remaining blocks required for transmit, ramps the PA, transmits the packet and returns to Standby mode.
…the datasheet describes the following in the Data Transmission Sequence:
- […]
- The LoRa FIFO can only be filled in Standby mode.
- Data transmission is initiated by sending TX mode request.
- Upon completion the TxDone interrupt is issued and the radio returns to Standby mode.
So: all without a word about activity detection or collision detection.
To detect if one should switch on receiving, channel activity detection is described as:
- […]
- Once the calculation is finished the modem generates the CadDone interrupt. If the correlation was successful, CadDetected is generated simultaneously.
- The chip goes back to Standby mode.
- If a preamble was detected, clear the interrupt, then initiate the reception by putting the radio in RX single mode or RX continuous mode.
For LoRaWAN, the IBM LMiC library also performs no activity detection before sending, neither in the high level examples, nor in the lower level library code. Like in radio.c
:
static void opmode (u1_t mode) {
writeReg(RegOpMode, (readReg(RegOpMode) & ~OPMODE_MASK) | mode);
}
static void txlora () {
// select LoRa modem (from sleep mode)
//writeReg(RegOpMode, OPMODE_LORA);
opmodeLora();
ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0);
// enter standby mode (required for FIFO loading))
opmode(OPMODE_STANDBY);
// configure LoRa modem (cfg1, cfg2)
configLoraModem();
// configure frequency
configChannel();
// configure output power
writeReg(RegPaRamp, (readReg(RegPaRamp) & 0xF0) | 0x08); // set PA ramp-up time 50 uSec
configPower();
// set sync word
writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE);
// set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP
writeReg(RegDioMapping1, MAP_DIO0_LORA_TXDONE|MAP_DIO1_LORA_NOP|MAP_DIO2_LORA_NOP);
// clear all radio IRQ flags
writeReg(LORARegIrqFlags, 0xFF);
// mask all IRQs but TxDone
writeReg(LORARegIrqFlagsMask, ~IRQ_LORA_TXDONE_MASK);
// initialize the payload size and address pointers
writeReg(LORARegFifoTxBaseAddr, 0x00);
writeReg(LORARegFifoAddrPtr, 0x00);
writeReg(LORARegPayloadLength, LMIC.dataLen);
// download buffer to the radio FIFO
writeBuf(RegFifo, LMIC.frame, LMIC.dataLen);
// enable antenna switch for TX
hal_pin_rxtx(1);
// now we actually start the transmission
opmode(OPMODE_TX);
}
And when handling the LoRa interrupts in radio_irq_handler
, only TxDone, RxDone and RxTimeout are expected, and for the first nothing is validated either:
// called by hal ext IRQ handler
// (radio goes to stanby mode after tx/rx operations)
void radio_irq_handler (u1_t dio) {
ostime_t now = os_getTime();
if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem
u1_t flags = readReg(LORARegIrqFlags);
if( flags & IRQ_LORA_TXDONE_MASK ) {
// save exact tx time
LMIC.txend = now - us2osticks(43); // TXDONE FIXUP
} else if( flags & IRQ_LORA_RXDONE_MASK ) {
...
} else if( flags & IRQ_LORA_RXTOUT_MASK ) {
...
}