Gemini/Diversity 900 (#1993)
[ExpressLRS.git] / src / lib / FHSS / FHSS.cpp
blob3dc9c4e56a5a03c49729eab9ffdf46fc52588eb6
1 #include "FHSS.h"
2 #include "logging.h"
3 #include "options.h"
4 #include <string.h>
6 #if defined(RADIO_SX127X)
7 #include "SX127xDriver.h"
9 const fhss_config_t domains[] = {
10 {"AU915", FREQ_HZ_TO_REG_VAL(915500000), FREQ_HZ_TO_REG_VAL(926900000), 20},
11 {"FCC915", FREQ_HZ_TO_REG_VAL(903500000), FREQ_HZ_TO_REG_VAL(926900000), 40},
12 {"EU868", FREQ_HZ_TO_REG_VAL(865275000), FREQ_HZ_TO_REG_VAL(869575000), 13},
13 {"IN866", FREQ_HZ_TO_REG_VAL(865375000), FREQ_HZ_TO_REG_VAL(866950000), 4},
14 {"AU433", FREQ_HZ_TO_REG_VAL(433420000), FREQ_HZ_TO_REG_VAL(434420000), 3},
15 {"EU433", FREQ_HZ_TO_REG_VAL(433100000), FREQ_HZ_TO_REG_VAL(434450000), 3}
17 #elif defined(RADIO_SX128X)
18 #include "SX1280Driver.h"
20 const fhss_config_t domains[] = {
22 #if defined(Regulatory_Domain_EU_CE_2400)
23 "CE_LBT",
24 #elif defined(Regulatory_Domain_ISM_2400)
25 "ISM2G4",
26 #endif
27 FREQ_HZ_TO_REG_VAL(2400400000), FREQ_HZ_TO_REG_VAL(2479400000), 80}
29 #endif
31 // Our table of FHSS frequencies. Define a regulatory domain to select the correct set for your location and radio
32 const fhss_config_t *FHSSconfig;
34 // Actual sequence of hops as indexes into the frequency list
35 uint8_t FHSSsequence[256];
36 // Which entry in the sequence we currently are on
37 uint8_t volatile FHSSptr;
38 // Channel for sync packets and initial connection establishment
39 uint_fast8_t sync_channel;
40 // Offset from the predefined frequency determined by AFC on Team900 (register units)
41 int32_t FreqCorrection;
42 int32_t FreqCorrection_2;
44 uint32_t freq_spread;
46 /**
47 Requirements:
48 1. 0 every n hops
49 2. No two repeated channels
50 3. Equal occurance of each (or as even as possible) of each channel
51 4. Pseudorandom
53 Approach:
54 Fill the sequence array with the sync channel every FHSS_FREQ_CNT
55 Iterate through the array, and for each block, swap each entry in it with
56 another random entry, excluding the sync channel.
59 void FHSSrandomiseFHSSsequence(const uint32_t seed)
61 FHSSconfig = &domains[firmwareOptions.domain];
62 INFOLN("Setting %s Mode", FHSSconfig->domain);
63 DBGLN("Number of FHSS frequencies = %u", FHSSconfig->freq_count);
65 sync_channel = (FHSSconfig->freq_count / 2) + 1;
66 DBGLN("Sync channel = %u", sync_channel);
68 freq_spread = (FHSSconfig->freq_stop - FHSSconfig->freq_start) * FREQ_SPREAD_SCALE / (FHSSconfig->freq_count - 1);
70 // reset the pointer (otherwise the tests fail)
71 FHSSptr = 0;
72 rngSeed(seed);
74 // initialize the sequence array
75 for (uint16_t i = 0; i < FHSSgetSequenceCount(); i++)
77 if (i % FHSSconfig->freq_count == 0) {
78 FHSSsequence[i] = sync_channel;
79 } else if (i % FHSSconfig->freq_count == sync_channel) {
80 FHSSsequence[i] = 0;
81 } else {
82 FHSSsequence[i] = i % FHSSconfig->freq_count;
86 for (uint16_t i=0; i < FHSSgetSequenceCount(); i++)
88 // if it's not the sync channel
89 if (i % FHSSconfig->freq_count != 0)
91 uint8_t offset = (i / FHSSconfig->freq_count) * FHSSconfig->freq_count; // offset to start of current block
92 uint8_t rand = rngN(FHSSconfig->freq_count-1)+1; // random number between 1 and FHSS_FREQ_CNT
94 // switch this entry and another random entry in the same block
95 uint8_t temp = FHSSsequence[i];
96 FHSSsequence[i] = FHSSsequence[offset+rand];
97 FHSSsequence[offset+rand] = temp;
101 // output FHSS sequence
102 for (uint16_t i=0; i < FHSSgetSequenceCount(); i++)
104 DBG("%u ",FHSSsequence[i]);
105 if (i % 10 == 9)
106 DBGCR;
108 DBGCR;
111 bool isDomain868()
113 return strcmp(FHSSconfig->domain, "EU868") == 0;