kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
72 wiersze
3.9 KiB
C++
72 wiersze
3.9 KiB
C++
#ifndef __FREQPLAN_H__
|
|
#define __FREQPLAN_H__
|
|
|
|
#include <stdint.h>
|
|
|
|
class FreqPlan
|
|
{ public:
|
|
uint8_t Plan; // 1=Europe, 2=USA/Canada, 3=Australia/Chile, 4=New Zeeland
|
|
uint8_t Channels; // number of channels
|
|
uint32_t BaseFreq; // [Hz] base channel (#0) frequency
|
|
uint32_t ChanSepar; // [Hz] channel spacing
|
|
static const uint8_t MaxChannels=65;
|
|
|
|
public:
|
|
void setPlan(uint8_t NewPlan=0) // preset for a given frequency plan
|
|
{ Plan=NewPlan;
|
|
if(Plan==2) { BaseFreq=902200000; ChanSepar=400000; Channels=65; } // USA
|
|
else if(Plan==3) { BaseFreq=917000000; ChanSepar=400000; Channels=24; } // Australia and South America
|
|
else if(Plan==4) { BaseFreq=869250000; ChanSepar=200000; Channels= 1; } // New Zeeland
|
|
else { BaseFreq=868200000; ChanSepar=200000; Channels= 2; } // Europe
|
|
}
|
|
|
|
void setPlan(int32_t Latitude, int32_t Longitude)
|
|
{ setPlan(calcPlan(Latitude, Longitude)); }
|
|
|
|
const char *getPlanName(void) { return getPlanName(Plan); }
|
|
|
|
static const char *getPlanName(uint8_t Plan)
|
|
{ static const char *Name[5] = { "Default", "Europe/Africa", "USA/Canada", "Australia/South America", "New Zeeland" } ;
|
|
if(Plan>4) return 0;
|
|
return Name[Plan]; }
|
|
|
|
uint8_t getChannel (uint32_t Time, uint8_t Slot=0, uint8_t OGN=1) const // OGN-tracker or FLARM, UTC time, slot: 0 or 1
|
|
{ if(Channels<=1) return 0; // if single channel (New Zeeland) return channel #0
|
|
if(Plan>=2) // if USA/Canada or Australia/South America
|
|
{ uint8_t Channel = FreqHopHash((Time<<1)+Slot) % Channels; // Flarm hopping channel
|
|
if(OGN) // for OGN tracker
|
|
{ if(Slot) { uint8_t Channel1=FreqHopHash((Time<<1)) % Channels; // for 2nd slot choose a channel close to the 1st slot
|
|
Channel1++; if(Channel1>=Channels) Channel1-=2; //
|
|
uint8_t Channel2=Channel1+1; if(Channel2>=Channels) Channel2-=2;
|
|
if(Channel2==Channel) Channel=Channel1; // avoid being on same chanel as Flarm
|
|
else Channel=Channel2; }
|
|
else { Channel++; if(Channel>=Channels) Channel-=2; } // for 1st slot choose a higher channel (unless already highest, then choose a lower one)
|
|
}
|
|
return Channel; } // return 0..Channels-1 for USA/CA or Australia.
|
|
return Slot^OGN; } // if Europe/South Africa: return 0 or 1 for EU freq. plan
|
|
|
|
uint32_t getChanFrequency(int Channel) const { return BaseFreq+ChanSepar*Channel; }
|
|
|
|
uint32_t getFrequency(uint32_t Time, uint8_t Slot=0, uint8_t OGN=1) const
|
|
{ uint8_t Channel=getChannel(Time, Slot, OGN); return BaseFreq+ChanSepar*Channel; } // return frequency [Hz] for given UTC time and slot
|
|
|
|
uint8_t static calcPlan(int32_t Latitude, int32_t Longitude) // get the frequency plan from Lat/Lon: 1 = Europe + Africa, 2 = USA/CAnada, 3 = Australia + South America, 4$
|
|
{ if( (Longitude>=(-20*600000)) && (Longitude<=(60*600000)) ) return 1; // between -20 and 60 deg Lat => Europe + Africa: 868MHz band
|
|
if( Latitude<(20*600000) ) // below 20deg latitude
|
|
{ if( ( Longitude>(164*600000)) && (Latitude<(-30*600000)) && (Latitude>(-48*600000)) ) return 4; // => New Zeeland
|
|
return 3; } // => Australia + South America: upper half of 915MHz band
|
|
return 2; } // => USA/Canada: full 915MHz band
|
|
|
|
private:
|
|
static uint32_t FreqHopHash(uint32_t Time)
|
|
{ Time = (Time<<15) + (~Time);
|
|
Time ^= Time>>12;
|
|
Time += Time<<2;
|
|
Time ^= Time>>4;
|
|
Time *= 2057;
|
|
return Time ^ (Time>>16); }
|
|
|
|
} ;
|
|
|
|
#endif // __FREQPLAN_H__
|