SX1278 fast frequency hopping

 lauantai, 8. heinäkuu 2017
SX1278 fast frequency hopping

Arduino Dragino Lora shield (Semtech SX1278 chip) can tune into frequency quite fast. Fasthop feature works at best in OOK continuous mode.
RegPllHop (0x44) bit 7:
Bypasses the main state machine for a quick frequency hop. Writing RegFrfLsb will trigger the frequency change.
1 -> Frf is validated triggered when RegFrfLsb is written.

1. set FastHopOn=1
2. set new Frf (*)
3. wait for TS_HOP
TS_HOP = Frequency synthesizer hop time at most 10 kHz away from the target frequency.
(*) RegFrfLsb must be written to trigger a frequency change.


 





SX1278 library: https://github.com/open-electronics/LoRa/releases

SX1278 datasheet: http://www.semtech.com/apps/filedown/down.php?file=sx1276_77_78_79.pdf

#include <SX1278.h>

#define SERIAL_SPEED        9600
#define F_START             433           // start freq
#define F_STEP              0.025         // 25 kHz step
#define F_CH                50            // channels to rx hop
#define BPS                 1200
#define STATE_STANDBY       1
#define STATE_FSRX          4
#define STATE_RX            5
#define H_DELAY             2
#define M_DELAY             10
#define L_DELAY             100
#define SX_BEGIN            "SX.begin"
#define SX_BITRATE          "SX.readBPS "
#define SX_FREQ             "SX.readFreq "
#define RSSI_THRESHOLD      -80             // dBm
#define CH_FILTER_BW        B00001100       // 25 kHz

#define RegRssiConfig       0x0e
#define RegRxBw             0x12
#define RegPacketConfig1    0x30

#define RegOpMode           0x01
#define RegPaRamp           0x0a
#define RegRssiThresh       0x10
#define RegOokPeak          0x14
#define RegPreambleDetect   0x1f
#define RegSyncConfig       0x27
#define RegPacketConfig2    0x31
#define RegIrqFlags1        0x3e
#define RegIrqFlags2        0x3f
#define RegPllHop           0x44

bool rx = false;

void setup() {
  Serial.begin(SERIAL_SPEED);
  if (SX.begin()) {
    Serial.println(F(SX_BEGIN));
    delay(M_DELAY);
    SX.startModeFSKOOK();
    // OOK
    byte b = SX.SPIread(RegOpMode);
    bitClear(b, 6);
    bitSet(b, 5);
    SX.SPIwrite(RegOpMode, b);

    fastHop(0);
    SX.setFreq(F_START);
    Serial.print(F(SX_FREQ));
    Serial.println(SX.readFreq(), DEC);
    SX.setBPS(BPS);
    Serial.print(F(SX_BITRATE));
    Serial.println(SX.readBPS(), DEC);

    // Channel filter bandwidth control
    SX.SPIwrite(RegRxBw, CH_FILTER_BW);
    
    // Bits 7-6: AutoRestartRxMode, 01 -> On, without waiting for the PLL to re-lock
    // Bit 4: Enables the Sync word generation and detection: 0 -> Off, 1 -> On
    // Bit 5: Sets the polarity of the Preamble. 0 -> 0xAA, 1 -> 0x55
    // Bits 2-0: Size of the Sync word (SyncSize + 1)
    b = SX.SPIread(RegSyncConfig);
    bitClear(b, 7);
    bitSet(b, 6);
    bitClear(b, 4);
    bitClear(b, 5);
    bitClear(b, 2);
    bitClear(b, 1);
    bitClear(b, 0);
    SX.SPIwrite(RegSyncConfig, b);

    // Bits 6-5: Defines DC-free encoding/decoding performed:
    // 00 -> none, 01 -> manchester, 10 -> whitening
    // Bit 7: packet format, 0 -> fixed length, 1 -> variable length
    // Bit 4: crc calc/check, 0 -> off, 1 -> on
    // Bits 2-1: Defines address based filtering in Rx: 00 ->Â None (Off)
    // Bit 3: Defines the behavior of the packet handler when CRC check fails:
    // 0 -> Clear FIFO and restart new packet reception. No PayloadReady interrupt issued.
    // 1 -> Do not clear FIFO. PayloadReady interrupt issued.
    // Bit 0: Selects the CRC and whitening algorithms:
    // 0 -> CCITT CRC implementation with standard whitening
    // 1 -> IBM CRC implementation with alternate whitening
    b = 0;
    SX.SPIwrite(RegPacketConfig1, b);

    // Bits 6-5: FSK data shaping:
    // 00 -> no shaping, 01 -> Gaussian filter BT = 1.0
    // 10 -> Gaussian filter BT = 0.5, 11 -> Gaussian filter BT = 0.3
    // Bits 3-0: Rise/Fall time of ramp up/down in FSK:
    // 1001 -> 40 us
    b = SX.SPIread(RegPaRamp);
    bitClear(b, 6);
    bitClear(b, 5);
    bitSet(b, 3);
    bitClear(b, 2);
    bitSet(b, 0);
    SX.SPIwrite(RegPaRamp, b);

    // Data processing mode: 0 ->Â Continuous mode, 1 -> Packet mode
    b = SX.SPIread(RegPacketConfig2);
    bitClear(b, 6);
    SX.SPIwrite(RegPacketConfig2, b);

    // RSSI smoothing.
    // Defines the number of samples taken to average the RSSI result. 001 -> 4 samples
    b = SX.SPIread(RegRssiConfig);
    bitClear(b, 2);
    bitClear(b, 1);
    bitSet(b, 0);
    SX.SPIwrite(RegRssiConfig, b);

    SX.SPIwrite(RegRssiThresh, RSSI_THRESHOLD);

    // Bit 5: enables the Bit Synchronizer:
    // 0 -> bit sync disabled (not possible in packet mode), 1 -> bit sync enabled
    b = SX.SPIread(RegOokPeak);
    bitClear(b, 5);
    SX.SPIwrite(RegOokPeak, b);

    // RegPreambleDetect (0x1f). Enables Preamble detector when set to 1.
    // The AGC settings supersede this bit during the startup / AGC phase.
    // Bit 7: 0 -> turned off, 1 -> turned on
    // Bits 6-5: Number of Preamble bytes to detect to trigger an interrupt.
    // 00 -> 1 byte, 10 -> 3 bytes, 01 -> 2 bytes
    b = SX.SPIread(RegPreambleDetect);
    bitClear(b, 7);
    bitClear(b, 6);
    bitClear(b, 5);
    SX.SPIwrite(RegPreambleDetect, b);

    clearFifoAndFlags();

    SX.setState(STATE_FSRX);
    delay(L_DELAY);
    SX.setState(STATE_RX);
    delay(M_DELAY);
 
    rx = true;
  }
}

void loop() {
  if (rx) {
    float f = F_START;
    for (int c = 0; c < F_CH; c++) {
      fastHop(1);
      SX.setFreq(f);
      delay(H_DELAY);

      float rssi = SX.readRSSIval();
      if (rssi > RSSI_THRESHOLD) {
        Serial.print(f, DEC);
        Serial.print("\t");
        Serial.println(rssi, DEC);
      }

      f = f + F_STEP;
    }
  }
}

void clearFifoAndFlags() {
  // Flag(s) and FIFO are cleared when this bit is set
  byte b = SX.SPIread(RegIrqFlags2);
  bitSet(b, 4);
  SX.SPIwrite(RegIrqFlags2, b);
  delay(M_DELAY);
}

void fastHop(int val) {
  byte b = SX.SPIread(RegPllHop);
  bitWrite(b, 7, val);
  SX.SPIwrite(RegPllHop, b);
}

Comments

Popular posts from this blog

Modifying old SDR# TETRA demod plug-in

Mods for SDR# TETRA demod plugin 1.0.14.0 - 2