Skip to content

Commit 9602fe7

Browse files
committed
Fix channel calculation for NARROW_868 region
Correct the `numChannels` and `radioFreq` calculations to align with the firmware logic. This primarily affects the NARROW_868 region by properly accounting for channel spacing. - Remove `regionInfo.spacing` from the `numChannels` numerator. - Add `regionInfo.spacing` to the `radioFreq` calculation. - Add tests to verify `numChannels` and `radioFreq` for the `NARROW_868` region.
1 parent f75edf2 commit 9602fe7

2 files changed

Lines changed: 27 additions & 6 deletions

File tree

core/model/src/main/kotlin/org/meshtastic/core/model/ChannelOption.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,9 @@ val LoRaConfig.numChannels: Int
7878
if (bw <= 0f) return 1 // Return 1 if bandwidth is zero or negative
7979

8080
// Calculate number of channels: spacing = gap between channels (0 for continuous spectrum)
81-
// Match firmware: uint32_t numChannels = round((myRegion->freqEnd - myRegion->freqStart + myRegion->spacing) /
82-
// channelSpacing);
81+
// Match firmware: uint32_t numChannels = round((myRegion->freqEnd - myRegion->freqStart) / channelSpacing);
8382
val channelSpacing = regionInfo.spacing + bw
84-
val num = Math.round((regionInfo.freqEnd - regionInfo.freqStart + regionInfo.spacing) / channelSpacing).toInt()
83+
val num = Math.round((regionInfo.freqEnd - regionInfo.freqStart) / channelSpacing).toInt()
8584

8685
// If the regional frequency range is smaller than the bandwidth, the firmware would
8786
// fall back to a default preset. In the app, we return 1 to avoid a crash.
@@ -100,13 +99,13 @@ internal fun LoRaConfig.radioFreq(channelNum: Int): Float {
10099
return if (regionInfo != null) {
101100
val bw = bandwidth(regionInfo)
102101
val channelSpacing = regionInfo.spacing + bw
103-
// Match firmware: float freq = myRegion->freqStart + (bw / 2000) + (channel_num * channelSpacing);
102+
// Match firmware: float freq = myRegion->freqStart + myRegion->spacing + (bw / 2000) + (channel_num * channelSpacing);
104103
// Note: firmware channel_num is 0-indexed in the calculation, but the app uses 1-indexed for some reason?
105104
// Let's re-verify the firmware logic.
106105
// Firmware: channel_num = hash(channelName) % numChannels;
107-
// freq = myRegion->freqStart + (bw / 2000) + (channel_num * channelSpacing);
106+
// freq = myRegion->freqStart + myRegion->spacing + (bw / 2000) + (channel_num * channelSpacing);
108107
// The app's channelNum function returns 1..numChannels if channelNum is 0.
109-
(regionInfo.freqStart + bw / 2) + (channelNum - 1) * channelSpacing
108+
(regionInfo.freqStart + regionInfo.spacing + bw / 2) + (channelNum - 1) * channelSpacing
110109
} else {
111110
0f
112111
}

core/model/src/test/kotlin/org/meshtastic/core/model/ChannelOptionTest.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ package org.meshtastic.core.model
2020
import org.junit.Assert.assertEquals
2121
import org.junit.Assert.assertNotNull
2222
import org.junit.Test
23+
import org.meshtastic.proto.ConfigKt.loRaConfig
2324
import org.meshtastic.proto.ConfigProtos.Config.LoRaConfig.ModemPreset
25+
import org.meshtastic.proto.ConfigProtos.Config.LoRaConfig.RegionCode
2426

2527
class ChannelOptionTest {
2628

@@ -78,4 +80,24 @@ class ChannelOptionTest {
7880
ChannelOption.entries.size,
7981
)
8082
}
83+
84+
@Test
85+
fun `test radioFreq and numChannels for NARROW_868`() {
86+
val loraConfig = loRaConfig {
87+
region = RegionCode.NARROW_868
88+
usePreset = true
89+
modemPreset = ModemPreset.NARROW_FAST
90+
}
91+
92+
// bw = 0.0625, spacing = 0.015, channelSpacing = 0.0775
93+
// Range = 869.65 - 869.4 = 0.25
94+
// numChannels = round(0.25 / 0.0775) = 3
95+
assertEquals(3, loraConfig.numChannels)
96+
97+
// Slot 1: freqStart + spacing + bw/2 = 869.4 + 0.015 + 0.03125 = 869.44625
98+
assertEquals(869.44625f, loraConfig.radioFreq(1), 0.0001f)
99+
100+
// Slot 3: 869.44625 + 2 * 0.0775 = 869.44625 + 0.155 = 869.60125
101+
assertEquals(869.60125f, loraConfig.radioFreq(3), 0.0001f)
102+
}
81103
}

0 commit comments

Comments
 (0)