mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
Fix setting illegal LoRaWan frequencies (#23388)
This commit is contained in:
parent
502cdfb9ea
commit
5475fcc8f3
@ -69,27 +69,45 @@ For Others, same Uplink/Downlink (TX/RX) frequencies may not be allowed.
|
|||||||
See: https://lora-alliance.org/wp-content/uploads/2020/11/RP_2-1.0.2.pdf
|
See: https://lora-alliance.org/wp-content/uploads/2020/11/RP_2-1.0.2.pdf
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Determines the channel from the current Uplink LoraSettings
|
uint32_t LoraWanFrequencyToChannel(void) {
|
||||||
// return 0..71
|
// Determines the channel from the current Uplink LoraSettings
|
||||||
uint32_t LoraWanChannel(void) {
|
uint32_t channel = 0;
|
||||||
float fFrequencyDiff;
|
|
||||||
uint8_t uChannel = 0;
|
|
||||||
|
|
||||||
switch (Lora->settings.region) {
|
switch (Lora->settings.region) {
|
||||||
case TAS_LORA_REGION_AU915:
|
case TAS_LORA_REGION_AU915:
|
||||||
if (125.0 == Lora->settings.bandwidth) {
|
// Return 0 .. 71
|
||||||
fFrequencyDiff = Lora->settings.frequency - TAS_LORAWAN_AU915_FREQUENCY_UP1;
|
if ((Lora->settings.frequency < 915.2) || (Lora->settings.frequency > 927.8)) {
|
||||||
uChannel = (0.01 + (fFrequencyDiff / 0.2)); // 0.01 to fix rounding errors
|
Lora->settings.frequency = TAS_LORAWAN_AU915_FREQUENCY_UP1; // Fix initial frequency
|
||||||
|
Lora->settings.bandwidth = TAS_LORAWAN_AU915_BANDWIDTH_UP1; // Fix initial bandwidth
|
||||||
|
}
|
||||||
|
else if (125.0 == Lora->settings.bandwidth) {
|
||||||
|
float fFrequencyDiff = Lora->settings.frequency - TAS_LORAWAN_AU915_FREQUENCY_UP1;
|
||||||
|
channel = (0.01 + (fFrequencyDiff / 0.2)); // 0.01 to fix rounding errors
|
||||||
} else {
|
} else {
|
||||||
fFrequencyDiff = Lora->settings.frequency - TAS_LORAWAN_AU915_FREQUENCY_UP2;
|
float fFrequencyDiff = Lora->settings.frequency - TAS_LORAWAN_AU915_FREQUENCY_UP2;
|
||||||
uChannel = 64 + ((0.01 + (fFrequencyDiff / 1.6)));
|
channel = 64 + ((0.01 + (fFrequencyDiff / 1.6)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default: // TAS_LORA_REGION_EU868
|
||||||
//default:
|
// EU863-870 (EU868) JoinReq message frequencies are 868.1, 868.3 and 868.5
|
||||||
//not implemented
|
uint32_t frequency = (Lora->settings.frequency * 10);
|
||||||
|
uint32_t channel = 250;
|
||||||
|
if (8681 == frequency) {
|
||||||
|
channel = 0;
|
||||||
|
}
|
||||||
|
else if (8683 == frequency) {
|
||||||
|
channel = 1;
|
||||||
|
}
|
||||||
|
else if (8685 == frequency) {
|
||||||
|
channel = 2;
|
||||||
|
}
|
||||||
|
if (250 == channel) {
|
||||||
|
Lora->settings.frequency = 868.1;
|
||||||
|
Lora->Config();
|
||||||
|
channel = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return uChannel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -103,7 +121,7 @@ uint32_t LoraWanChannel(void) {
|
|||||||
const uint8_t RX1DRs[] PROGMEM = {8,9,10,11,12,13,13}; // DR0..6
|
const uint8_t RX1DRs[] PROGMEM = {8,9,10,11,12,13,13}; // DR0..6
|
||||||
const uint8_t SF[] PROGMEM = {12,11,10,9,8,7,8,0,12,11,10,9,8,7}; // DR0..13
|
const uint8_t SF[] PROGMEM = {12,11,10,9,8,7,8,0,12,11,10,9,8,7}; // DR0..13
|
||||||
|
|
||||||
void LoraWanRadioInfo(uint8_t mode, void* pInfo) {
|
void LoraWanRadioInfo(uint8_t mode, void* pInfo, uint32_t uChannel = 0) {
|
||||||
LoRaWanRadioInfo_t* pResult = (LoRaWanRadioInfo_t*) pInfo;
|
LoRaWanRadioInfo_t* pResult = (LoRaWanRadioInfo_t*) pInfo;
|
||||||
|
|
||||||
switch (Lora->settings.region) {
|
switch (Lora->settings.region) {
|
||||||
@ -166,8 +184,7 @@ void LoraWanRadioInfo(uint8_t mode, void* pInfo) {
|
|||||||
|
|
||||||
Tasmota does not support different RX1 & RX2 DRs (yet), so just use DR8 and rely on RX2 arriving at end device OK.
|
Tasmota does not support different RX1 & RX2 DRs (yet), so just use DR8 and rely on RX2 arriving at end device OK.
|
||||||
*/
|
*/
|
||||||
uint32_t uChannel = LoraWanChannel();
|
uint8_t UplinkChannelBand = LoraWanFrequencyToChannel() %8; // 0..7
|
||||||
uint8_t UplinkChannelBand = uChannel %8; //0..7
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case TAS_LORAWAN_RADIO_UPLINK: {
|
case TAS_LORAWAN_RADIO_UPLINK: {
|
||||||
// if (uChannel > 71) uChannel = 71; See note above
|
// if (uChannel > 71) uChannel = 71; See note above
|
||||||
@ -224,11 +241,8 @@ bool LoraWanDefaults(uint32_t region = TAS_LORA_REGION_EU868, LoRaWanRadioMode_t
|
|||||||
// TO DO: Need 3 profiles: Uplink, RX1, RX2
|
// TO DO: Need 3 profiles: Uplink, RX1, RX2
|
||||||
// Works OK for now as RX2 always received by end device.
|
// Works OK for now as RX2 always received by end device.
|
||||||
multi_profile = true;
|
multi_profile = true;
|
||||||
if ((Lora->settings.frequency < 915.2) || (Lora->settings.frequency > 927.8)) {
|
|
||||||
Lora->settings.frequency = TAS_LORAWAN_AU915_FREQUENCY_UP1;
|
|
||||||
}
|
|
||||||
LoRaWanRadioInfo_t RadioInfo;
|
LoRaWanRadioInfo_t RadioInfo;
|
||||||
LoraWanRadioInfo(mode, &RadioInfo); // Region specific
|
LoraWanRadioInfo(mode, &RadioInfo, LoraWanFrequencyToChannel()); // Region specific
|
||||||
Lora->settings.frequency = RadioInfo.frequency;
|
Lora->settings.frequency = RadioInfo.frequency;
|
||||||
Lora->settings.bandwidth = RadioInfo.bandwidth;
|
Lora->settings.bandwidth = RadioInfo.bandwidth;
|
||||||
Lora->settings.spreading_factor = RadioInfo.spreading_factor;
|
Lora->settings.spreading_factor = RadioInfo.spreading_factor;
|
||||||
@ -405,7 +419,7 @@ size_t LoraWanCFList(uint8_t * CFList, size_t uLen) {
|
|||||||
case TAS_LORA_REGION_AU915: {
|
case TAS_LORA_REGION_AU915: {
|
||||||
if (uLen < 16) return 0;
|
if (uLen < 16) return 0;
|
||||||
|
|
||||||
uint8_t uChannel = LoraWanChannel(); // 0..71
|
uint8_t uChannel = LoraWanFrequencyToChannel(); // 0..71
|
||||||
uint8_t uMaskByte = uChannel /8; // 0..8
|
uint8_t uMaskByte = uChannel /8; // 0..8
|
||||||
|
|
||||||
// Add first 10 bytes
|
// Add first 10 bytes
|
||||||
@ -455,27 +469,6 @@ uint32_t LoraWanSpreadingFactorToDataRate(bool downlink) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t LoraWanFrequencyToChannel(void) {
|
|
||||||
// EU863-870 (EU868) JoinReq message frequencies are 868.1, 868.3 and 868.5
|
|
||||||
uint32_t frequency = (Lora->settings.frequency * 10);
|
|
||||||
uint32_t channel = 250;
|
|
||||||
if (8681 == frequency) {
|
|
||||||
channel = 0;
|
|
||||||
}
|
|
||||||
else if (8683 == frequency) {
|
|
||||||
channel = 1;
|
|
||||||
}
|
|
||||||
else if (8685 == frequency) {
|
|
||||||
channel = 2;
|
|
||||||
}
|
|
||||||
if (250 == channel) {
|
|
||||||
Lora->settings.frequency = 868.1;
|
|
||||||
Lora->Config();
|
|
||||||
channel = 0;
|
|
||||||
}
|
|
||||||
return channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************/
|
/*********************************************************************************************/
|
||||||
|
|
||||||
void LoraWanSendLinkADRReq(uint32_t node) {
|
void LoraWanSendLinkADRReq(uint32_t node) {
|
||||||
@ -500,9 +493,9 @@ void LoraWanSendLinkADRReq(uint32_t node) {
|
|||||||
case TAS_LORA_REGION_AU915: {
|
case TAS_LORA_REGION_AU915: {
|
||||||
//Ref: https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
//Ref: https://lora-alliance.org/wp-content/uploads/2020/11/lorawan_regional_parameters_v1.0.3reva_0.pdf
|
||||||
// page 39
|
// page 39
|
||||||
uint8_t uChannel = LoraWanChannel(); // 0..71
|
uint8_t uChannel = LoraWanFrequencyToChannel(); // 0..71
|
||||||
uint8_t ChMaskCntl = uChannel/16.0; // 0..4
|
uint8_t ChMaskCntl = uChannel /16.0; // 0..4
|
||||||
uChannel = uChannel%16; // 0..15
|
uChannel = uChannel %16; // 0..15
|
||||||
uint16_t uMask = 0x01 << uChannel;
|
uint16_t uMask = 0x01 << uChannel;
|
||||||
|
|
||||||
data[9] = LoraWanSpreadingFactorToDataRate(false) << 4 | 0x0F; // Uplink DataRate_TXPower Should be 'DR2' for & 'unchanged' = 0x2F
|
data[9] = LoraWanSpreadingFactorToDataRate(false) << 4 | 0x0F; // Uplink DataRate_TXPower Should be 'DR2' for & 'unchanged' = 0x2F
|
||||||
|
@ -48,17 +48,17 @@ void LoraSettings2Json(bool show = false) {
|
|||||||
#ifdef USE_LORAWAN_BRIDGE
|
#ifdef USE_LORAWAN_BRIDGE
|
||||||
if (show && (Lora->settings.region == TAS_LORA_REGION_AU915)) {
|
if (show && (Lora->settings.region == TAS_LORA_REGION_AU915)) {
|
||||||
LoRaWanRadioInfo_t Rx1Info;
|
LoRaWanRadioInfo_t Rx1Info;
|
||||||
LoraWanRadioInfo(TAS_LORAWAN_RADIO_RX1, &Rx1Info); // Get Rx1Info with values used for RX1 transmit window. (Region specific, calculated from Uplink radio settings)
|
LoraWanRadioInfo(TAS_LORAWAN_RADIO_RX1, &Rx1Info, LoraWanFrequencyToChannel()); // Get Rx1Info with values used for RX1 transmit window. (Region specific, calculated from Uplink radio settings)
|
||||||
LoRaWanRadioInfo_t Rx2Info;
|
LoRaWanRadioInfo_t Rx2Info;
|
||||||
LoraWanRadioInfo(TAS_LORAWAN_RADIO_RX2, &Rx2Info); // Get Rx2Info
|
LoraWanRadioInfo(TAS_LORAWAN_RADIO_RX2, &Rx2Info, LoraWanFrequencyToChannel()); // Get Rx2Info
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":[%1_f,%1_f,%1_f]"), &Lora->settings.frequency, &Rx1Info.frequency, &Rx2Info.frequency); // xxx.x MHz
|
ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":[%1_f,%1_f,%1_f]"), &Lora->settings.frequency, &Rx1Info.frequency, &Rx2Info.frequency); // xxx.x MHz
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_BANDWIDTH "\":[%1_f,%1_f,%1_f]"), &Lora->settings.bandwidth, &Rx1Info.bandwidth, &Rx2Info.bandwidth); // xxx.x kHz
|
ResponseAppend_P(PSTR(",\"" D_JSON_BANDWIDTH "\":[%1_f,%1_f,%1_f]"), &Lora->settings.bandwidth, &Rx1Info.bandwidth, &Rx2Info.bandwidth); // xxx.x kHz
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_SPREADING_FACTOR "\":[%d,%d,%d]"), Lora->settings.spreading_factor, Rx1Info.spreading_factor, Rx2Info.spreading_factor);
|
ResponseAppend_P(PSTR(",\"" D_JSON_SPREADING_FACTOR "\":[%d,%d,%d]"), Lora->settings.spreading_factor, Rx1Info.spreading_factor, Rx2Info.spreading_factor);
|
||||||
} else
|
} else
|
||||||
#endif // USE_LORAWAN_BRIDGE
|
#endif // USE_LORAWAN_BRIDGE
|
||||||
{
|
{
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":%1_f"), &Lora->settings.frequency); // xxx.x MHz
|
ResponseAppend_P(PSTR(",\"" D_JSON_FREQUENCY "\":%1_f"), &Lora->settings.frequency); // xxx.x MHz
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_BANDWIDTH "\":%1_f"), &Lora->settings.bandwidth); // xxx.x kHz
|
ResponseAppend_P(PSTR(",\"" D_JSON_BANDWIDTH "\":%1_f"), &Lora->settings.bandwidth); // xxx.x kHz
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_SPREADING_FACTOR "\":%d"), Lora->settings.spreading_factor);
|
ResponseAppend_P(PSTR(",\"" D_JSON_SPREADING_FACTOR "\":%d"), Lora->settings.spreading_factor);
|
||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR(",\"" D_JSON_CODINGRATE4 "\":%d"), Lora->settings.coding_rate);
|
ResponseAppend_P(PSTR(",\"" D_JSON_CODINGRATE4 "\":%d"), Lora->settings.coding_rate);
|
||||||
@ -443,19 +443,33 @@ void CmndLoraConfig(void) {
|
|||||||
// LoRaConfig 1 - Set EU868 default parameters
|
// LoRaConfig 1 - Set EU868 default parameters
|
||||||
// LoRaConfig 2 - Set EU868 default LoRaWan bridge parameters
|
// LoRaConfig 2 - Set EU868 default LoRaWan bridge parameters
|
||||||
// LoRaConfig 41 - Set AU915 default parameters
|
// LoRaConfig 41 - Set AU915 default parameters
|
||||||
// LoRaConfig 42 - Set AU915 default LoRaWan bridge parameters
|
// LoRaConfig 42 - Set AU915 default LoRaWan bridge parameters with channel 0
|
||||||
|
// LoRaConfig 42,10 - Set AU915 default LoRaWan bridge parameters with channel 10
|
||||||
// LoRaConfig {"Frequency":868.0,"Bandwidth":125.0} - Enter float parameters
|
// LoRaConfig {"Frequency":868.0,"Bandwidth":125.0} - Enter float parameters
|
||||||
// LoRaConfig {"SyncWord":18} - Enter decimal parameter (=0x12)
|
// LoRaConfig {"SyncWord":18} - Enter decimal parameter (=0x12)
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
if (XdrvMailbox.payload > 0) {
|
if (XdrvMailbox.payload > 0) {
|
||||||
uint32_t region = XdrvMailbox.payload / 10;
|
uint32_t region = (XdrvMailbox.payload / 10) &0x0F; // 0 .. 15
|
||||||
uint32_t option = ((XdrvMailbox.payload -1) &1) +1; // Option 1 or 2
|
if (region > 9) { region = 0; } // 0 .. 9
|
||||||
|
uint32_t option = ((XdrvMailbox.payload -1) &0x01) +1; // Option 1 or 2
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 1:
|
case 1:
|
||||||
LoraDefaults(region); // Default region LoRa values
|
LoraDefaults(region); // Default region LoRa values
|
||||||
break;
|
break;
|
||||||
#ifdef USE_LORAWAN_BRIDGE
|
#ifdef USE_LORAWAN_BRIDGE
|
||||||
case 2:
|
case 2:
|
||||||
|
switch (region) {
|
||||||
|
case TAS_LORA_REGION_AU915:
|
||||||
|
uint32_t parm[2] = { 0, 0 };
|
||||||
|
ParseParameters(2, parm); // parm[1] will hold channel
|
||||||
|
Lora->settings.region = region; // Need valid region for LoraWanRadioInfo()
|
||||||
|
LoRaWanRadioInfo_t UpInfo;
|
||||||
|
LoraWanRadioInfo(TAS_LORAWAN_RADIO_UPLINK, &UpInfo, parm[1]); // Set uplink frequency based on channel
|
||||||
|
Lora->settings.frequency = UpInfo.frequency;
|
||||||
|
break;
|
||||||
|
// default:
|
||||||
|
// not implemented
|
||||||
|
}
|
||||||
LoraWanDefaults(region); // Default region LoRaWan values
|
LoraWanDefaults(region); // Default region LoRaWan values
|
||||||
break;
|
break;
|
||||||
#endif // USE_LORAWAN_BRIDGE
|
#endif // USE_LORAWAN_BRIDGE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user