diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp index 33bcbcdce..116462e3a 100644 --- a/src/mesh/Channels.cpp +++ b/src/mesh/Channels.cpp @@ -84,10 +84,7 @@ void Channels::initDefaultChannel(ChannelIndex chIndex) Channel &ch = getByIndex(chIndex); ChannelSettings &channelSettings = ch.settings; - // radioConfig.modem_config = RadioConfig_ModemConfig_Bw125Cr45Sf128; // medium range and 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.modem_config = ChannelSettings_ModemConfig_LongSlow; // Default to Long Range & Fast channelSettings.tx_power = 0; // default uint8_t defaultpskIndex = 1; @@ -216,24 +213,27 @@ const char *Channels::getName(size_t chIndex) channelName = "Unset"; else switch (channelSettings.modem_config) { - case ChannelSettings_ModemConfig_Bw125Cr45Sf128: + case ChannelSettings_ModemConfig_ShortSlow: channelName = "ShortSlow"; break; - case ChannelSettings_ModemConfig_Bw500Cr45Sf128: + case ChannelSettings_ModemConfig_ShortFast: channelName = "ShortFast"; break; - case ChannelSettings_ModemConfig_Bw31_25Cr48Sf512: - channelName = "LongFast"; - break; - case ChannelSettings_ModemConfig_Bw125Cr48Sf4096: - channelName = "LongSlow"; - break; - case ChannelSettings_ModemConfig_Bw250Cr46Sf2048: + case ChannelSettings_ModemConfig_MidSlow: channelName = "MediumSlow"; break; - case ChannelSettings_ModemConfig_Bw250Cr47Sf1024: + case ChannelSettings_ModemConfig_MidFast: channelName = "MediumFast"; break; + case ChannelSettings_ModemConfig_LongFast: + channelName = "LongFast"; + break; + case ChannelSettings_ModemConfig_LongSlow: + channelName = "LongSlow"; + break; + case ChannelSettings_ModemConfig_VLongSlow: + channelName = "VLongSlow"; + break; default: channelName = "Invalid"; break; diff --git a/src/mesh/MeshRadio.h b/src/mesh/MeshRadio.h index 02e775464..1b1437123 100644 --- a/src/mesh/MeshRadio.h +++ b/src/mesh/MeshRadio.h @@ -8,10 +8,13 @@ // Map from old region names to new region enums struct RegionInfo { RegionCode code; - uint8_t numChannels; - uint8_t powerLimit; // Or zero for not set - float freq; + float freqStart; + float freqEnd; + float dutyCycle; float spacing; + uint8_t powerLimit; // Or zero for not set + bool audioPermitted; + bool freqSwitching; const char *name; // EU433 etc }; diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 269f6a071..97275825d 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -1,4 +1,3 @@ -#include "configuration.h" #include "RadioInterface.h" #include "Channels.h" #include "MeshRadio.h" @@ -6,45 +5,86 @@ #include "NodeDB.h" #include "Router.h" #include "assert.h" +#include "configuration.h" #include "sleep.h" #include #include #include -#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[] = { - 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), - RDEF(JP, 920.0f, 0.5f, 10, 13), // See https://github.com/meshtastic/Meshtastic-device/issues/346 power level 13 - 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 - // 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 - RDEF(Unset, 903.08f, 2.16f, 13, 0) // Assume US freqs if unset, Must be last + /* + https://link.springer.com/content/pdf/bbm%3A978-1-4842-4357-2%2F1.pdf + https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/ + */ + RDEF(US, 902.0f, 928.0f, 100, 0, 30, true, false), + + /* + https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf + */ + 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; void initRegion() @@ -55,7 +95,8 @@ void initRegion() myRegion = r; 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(); if (channelSettings.spread_factor == 0) { switch (channelSettings.modem_config) { - case ChannelSettings_ModemConfig_Bw125Cr45Sf128: ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium - ///< range - bw = 125; - cr = 5; + case ChannelSettings_ModemConfig_ShortFast: + bw = 250; + cr = 8; sf = 7; break; - case ChannelSettings_ModemConfig_Bw500Cr45Sf128: ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short - ///< range - bw = 500; - cr = 5; - sf = 7; + case ChannelSettings_ModemConfig_ShortSlow: + bw = 250; + cr = 8; + sf = 8; break; - case ChannelSettings_ModemConfig_Bw31_25Cr48Sf512: ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long - ///< range - bw = 31.25; + case ChannelSettings_ModemConfig_MidFast: + bw = 250; cr = 8; sf = 9; 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; cr = 8; sf = 12; break; - case ChannelSettings_ModemConfig_Bw250Cr46Sf2048: - bw = 250; - cr = 6; - sf = 11; - break; - case ChannelSettings_ModemConfig_Bw250Cr47Sf1024: - bw = 250; - cr = 7; - sf = 10; + case ChannelSettings_ModemConfig_VLongSlow: + bw = 31.25; + cr = 8; + sf = 12; break; default: assert(0); // Unknown enum @@ -327,20 +370,21 @@ void RadioInterface::applyModemConfig() 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 const char *channelName = channels.getName(channels.getPrimaryIndex()); - int channel_num = channelSettings.channel_num ? channelSettings.channel_num - 1 : hash(channelName) % myRegion->numChannels; - float freq = myRegion->freq + radioConfig.preferences.frequency_offset + myRegion->spacing * channel_num; - + int channel_num = channelSettings.channel_num ? channelSettings.channel_num - 1 : hash(channelName) % numChannels; + float freq = myRegion->freqStart+(((myRegion->freqEnd - myRegion->freqStart/numChannels)/2)*1); saveChannelNum(channel_num); saveFreq(freq); 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->spacing: %f\n", myRegion->spacing); - DEBUG_MSG("Radio myRegion->numChannels: %d\n", myRegion->numChannels); + DEBUG_MSG("Radio myRegion->freqStart / myRegion->freqEnd: %f / %f\n", myRegion->freqStart, myRegion->freqEnd); + DEBUG_MSG("Radio myRegion->numChannels: %d\n", numChannels); 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); }