New bands, new band plans and new channel configurations

This commit is contained in:
Jm Casler 2022-02-14 19:32:31 -08:00
parent 449926cff9
commit 96b5537217
3 changed files with 123 additions and 76 deletions

View File

@ -84,10 +84,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex)
Channel &ch = getByIndex(chIndex); Channel &ch = getByIndex(chIndex);
ChannelSettings &channelSettings = ch.settings; ChannelSettings &channelSettings = ch.settings;
// radioConfig.modem_config = RadioConfig_ModemConfig_Bw125Cr45Sf128; // medium range and fast channelSettings.modem_config = ChannelSettings_ModemConfig_LongSlow; // Default to Long Range & Fast
// channelSettings.modem_config = ChannelSettings_ModemConfig_Bw500Cr45Sf128; // short range and fast, but wide
// bandwidth so incompatible radios can talk together
channelSettings.modem_config = ChannelSettings_ModemConfig_Bw125Cr48Sf4096; // slow and long range
channelSettings.tx_power = 0; // default channelSettings.tx_power = 0; // default
uint8_t defaultpskIndex = 1; uint8_t defaultpskIndex = 1;
@ -216,24 +213,27 @@ const char *Channels::getName(size_t chIndex)
channelName = "Unset"; channelName = "Unset";
else else
switch (channelSettings.modem_config) { switch (channelSettings.modem_config) {
case ChannelSettings_ModemConfig_Bw125Cr45Sf128: case ChannelSettings_ModemConfig_ShortSlow:
channelName = "ShortSlow"; channelName = "ShortSlow";
break; break;
case ChannelSettings_ModemConfig_Bw500Cr45Sf128: case ChannelSettings_ModemConfig_ShortFast:
channelName = "ShortFast"; channelName = "ShortFast";
break; break;
case ChannelSettings_ModemConfig_Bw31_25Cr48Sf512: case ChannelSettings_ModemConfig_MidSlow:
channelName = "LongFast";
break;
case ChannelSettings_ModemConfig_Bw125Cr48Sf4096:
channelName = "LongSlow";
break;
case ChannelSettings_ModemConfig_Bw250Cr46Sf2048:
channelName = "MediumSlow"; channelName = "MediumSlow";
break; break;
case ChannelSettings_ModemConfig_Bw250Cr47Sf1024: case ChannelSettings_ModemConfig_MidFast:
channelName = "MediumFast"; channelName = "MediumFast";
break; break;
case ChannelSettings_ModemConfig_LongFast:
channelName = "LongFast";
break;
case ChannelSettings_ModemConfig_LongSlow:
channelName = "LongSlow";
break;
case ChannelSettings_ModemConfig_VLongSlow:
channelName = "VLongSlow";
break;
default: default:
channelName = "Invalid"; channelName = "Invalid";
break; break;

View File

@ -8,10 +8,13 @@
// Map from old region names to new region enums // Map from old region names to new region enums
struct RegionInfo { struct RegionInfo {
RegionCode code; RegionCode code;
uint8_t numChannels; float freqStart;
uint8_t powerLimit; // Or zero for not set float freqEnd;
float freq; float dutyCycle;
float spacing; float spacing;
uint8_t powerLimit; // Or zero for not set
bool audioPermitted;
bool freqSwitching;
const char *name; // EU433 etc const char *name; // EU433 etc
}; };

View File

@ -1,4 +1,3 @@
#include "configuration.h"
#include "RadioInterface.h" #include "RadioInterface.h"
#include "Channels.h" #include "Channels.h"
#include "MeshRadio.h" #include "MeshRadio.h"
@ -6,45 +5,86 @@
#include "NodeDB.h" #include "NodeDB.h"
#include "Router.h" #include "Router.h"
#include "assert.h" #include "assert.h"
#include "configuration.h"
#include "sleep.h" #include "sleep.h"
#include <assert.h> #include <assert.h>
#include <pb_decode.h> #include <pb_decode.h>
#include <pb_encode.h> #include <pb_encode.h>
#define RDEF(name, freq, spacing, num_ch, power_limit) \ #define RDEF(name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching) \
{ \ { \
RegionCode_##name, num_ch, power_limit, freq, spacing, #name \ RegionCode_##name, freq_start, freq_end, duty_cycle, spacing, power_limit, audio_permitted, frequency_switching, #name \
} }
const RegionInfo regions[] = { const RegionInfo regions[] = {
RDEF(US, 903.08f, 2.16f, 13, 0), RDEF(EU433, 433.175f, 0.2f, 8, 0), RDEF(EU865, 865.2f, 0.3f, 10, 0), /*
RDEF(CN, 470.0f, 2.0f, 20, 0), https://link.springer.com/content/pdf/bbm%3A978-1-4842-4357-2%2F1.pdf
RDEF(JP, 920.0f, 0.5f, 10, 13), // See https://github.com/meshtastic/Meshtastic-device/issues/346 power level 13 https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/
RDEF(ANZ, 916.0f, 0.5f, 20, 0), // AU/NZ channel settings 915-928MHz */
RDEF(KR, 921.9f, 0.2f, 8, 0), // KR channel settings (KR920-923) Start from TTN download channel RDEF(US, 902.0f, 928.0f, 100, 0, 30, true, false),
// freq. (921.9f is for download, others are for uplink)
RDEF(TW, 923.0f, 0.2f, 10, 0), // TW channel settings (AS2 bandplan 923-925MHz) /*
RDEF(RU, 868.9f, 0.2f, 2, 20), // See notes below https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
RDEF(Unset, 903.08f, 2.16f, 13, 0) // Assume US freqs if unset, Must be last */
RDEF(EU433, 433.0f, 434.0f, 10, 0, 12, true, false),
/*
https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/
https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/
https://www.legislation.gov.uk/uksi/1999/930/schedule/6/part/III/made/data.xht?view=snippet&wrap=true
*/
RDEF(EU868, 869.4f, 869.65f, 10, 0, 16, false, false),
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/
RDEF(CN, 470.0f, 510.0f, 100, 0, 19, true, false),
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/
RDEF(JP, 920.8f, 927.8f, 100, 0, 16, true, false),
/*
???
*/
RDEF(ANZ, 915.0f, 928.0f, 100, 0, 0, true, false),
/*
https://digital.gov.ru/uploaded/files/prilozhenie-12-k-reshenyu-gkrch-18-46-03-1.pdf
Note:
- We do LBT, so 100% is allowed.
*/
RDEF(RU, 868.7f, 869.2f, 100, 0, 20, true, false),
/*
???
*/
RDEF(KR, 920.0f, 923.0f, 100, 0, 0, true, false),
/*
???
*/
RDEF(TW, 920.0f, 925.0f, 100, 0, 0, true, false),
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/
RDEF(IN, 865.0f, 867.0f, 100, 0, 30, true, false),
/*
https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
*/
RDEF(TH, 920.0f, 925.0f, 100, 0, 16, true, false),
/*
This needs to be last. Same as US.
*/
RDEF(Unset, 902.0f, 928.0f, 100, 0, 30, true, false)
}; };
/* Notes about the RU bandplan (from @denis-d in https://meshtastic.discourse.group/t/russian-band-plan-proposal/2786/2):
According to Annex 12 to GKRCh (National Radio Frequency Commission) decision 18-46-03-1 (September 11th 2018)
https://digital.gov.ru/uploaded/files/prilozhenie-12-k-reshenyu-gkrch-18-46-03-1.pdf 1 We have 3 options for 868 MHz:
864,0 - 865,0 MHz ERP 25mW, Duty Cycle 0.1% (3.6 sec in hour) or LBT (Listen Before Talk), prohibited in airports.
866,0 - 868,0 MHz ERP 25mW, Duty Cycle 1% or LBT, PSD (Power Spectrum Density) 1000mW/MHz, prohibited in airports
868,7 - 869,2 MHz ERP 100mW, Duty Cycle 10% or LBT, no resctrictions
and according to RP2-1.0.2 LoRaWAN® Regional Parameters RP2-1.0.2 LoRaWAN® Regional Parameters - LoRa Alliance®
I propose to use following meshtastic bandplan:
1 channel - central frequency 868.9MHz 125kHz band
Protective band - 75kHz
2 channel - central frequency 869.1MHz 125kHz band
RDEF(RU, 868.9f, 0.2f, 2, 20)
*/
const RegionInfo *myRegion; const RegionInfo *myRegion;
void initRegion() void initRegion()
@ -55,7 +95,8 @@ void initRegion()
myRegion = r; myRegion = r;
DEBUG_MSG("Wanted region %d, using %s\n", radioConfig.preferences.region, r->name); DEBUG_MSG("Wanted region %d, using %s\n", radioConfig.preferences.region, r->name);
myNodeInfo.num_bands = myRegion->numChannels; // Tell our android app how many channels we have // myNodeInfo.num_bands = myRegion->numChannels; // Tell our android app how many channels we have
myNodeInfo.num_bands = 666; // JM Fixme!
} }
/** /**
@ -274,38 +315,40 @@ void RadioInterface::applyModemConfig()
auto channelSettings = channels.getPrimary(); auto channelSettings = channels.getPrimary();
if (channelSettings.spread_factor == 0) { if (channelSettings.spread_factor == 0) {
switch (channelSettings.modem_config) { switch (channelSettings.modem_config) {
case ChannelSettings_ModemConfig_Bw125Cr45Sf128: ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium case ChannelSettings_ModemConfig_ShortFast:
///< range bw = 250;
bw = 125; cr = 8;
cr = 5;
sf = 7; sf = 7;
break; break;
case ChannelSettings_ModemConfig_Bw500Cr45Sf128: ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short case ChannelSettings_ModemConfig_ShortSlow:
///< range bw = 250;
bw = 500; cr = 8;
cr = 5; sf = 8;
sf = 7;
break; break;
case ChannelSettings_ModemConfig_Bw31_25Cr48Sf512: ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long case ChannelSettings_ModemConfig_MidFast:
///< range bw = 250;
bw = 31.25;
cr = 8; cr = 8;
sf = 9; sf = 9;
break; break;
case ChannelSettings_ModemConfig_Bw125Cr48Sf4096: case ChannelSettings_ModemConfig_MidSlow:
bw = 250;
cr = 8;
sf = 10;
break;
case ChannelSettings_ModemConfig_LongSlow:
bw = 250;
cr = 8;
sf = 11;
break;
case ChannelSettings_ModemConfig_LongFast:
bw = 125; bw = 125;
cr = 8; cr = 8;
sf = 12; sf = 12;
break; break;
case ChannelSettings_ModemConfig_Bw250Cr46Sf2048: case ChannelSettings_ModemConfig_VLongSlow:
bw = 250; bw = 31.25;
cr = 6; cr = 8;
sf = 11; sf = 12;
break;
case ChannelSettings_ModemConfig_Bw250Cr47Sf1024:
bw = 250;
cr = 7;
sf = 10;
break; break;
default: default:
assert(0); // Unknown enum assert(0); // Unknown enum
@ -327,20 +370,21 @@ void RadioInterface::applyModemConfig()
assert(myRegion); // Should have been found in init assert(myRegion); // Should have been found in init
// Calculate the number of channels
uint32_t numChannels = floor((myRegion->freqEnd - myRegion->freqStart)/(myRegion->spacing + bw));
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name // If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
const char *channelName = channels.getName(channels.getPrimaryIndex()); const char *channelName = channels.getName(channels.getPrimaryIndex());
int channel_num = channelSettings.channel_num ? channelSettings.channel_num - 1 : hash(channelName) % myRegion->numChannels; int channel_num = channelSettings.channel_num ? channelSettings.channel_num - 1 : hash(channelName) % numChannels;
float freq = myRegion->freq + radioConfig.preferences.frequency_offset + myRegion->spacing * channel_num; float freq = myRegion->freqStart+(((myRegion->freqEnd - myRegion->freqStart/numChannels)/2)*1);
saveChannelNum(channel_num); saveChannelNum(channel_num);
saveFreq(freq); saveFreq(freq);
DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, channelSettings.modem_config, channel_num, power); DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, channelSettings.modem_config, channel_num, power);
DEBUG_MSG("Radio myRegion->freq: %f\n", myRegion->freq); DEBUG_MSG("Radio myRegion->freqStart / myRegion->freqEnd: %f / %f\n", myRegion->freqStart, myRegion->freqEnd);
DEBUG_MSG("Radio myRegion->spacing: %f\n", myRegion->spacing); DEBUG_MSG("Radio myRegion->numChannels: %d\n", numChannels);
DEBUG_MSG("Radio myRegion->numChannels: %d\n", myRegion->numChannels);
DEBUG_MSG("Radio channel_num: %d\n", channel_num); DEBUG_MSG("Radio channel_num: %d\n", channel_num);
DEBUG_MSG("Radio frequency: %f\n", getFreq()); // the frequency could be overridden in RadioInterface::getFreq() for some modules DEBUG_MSG("Radio frequency: %f\n", getFreq());
DEBUG_MSG("Short packet time: %u msec\n", shortPacketMsec); DEBUG_MSG("Short packet time: %u msec\n", shortPacketMsec);
} }