From 0d9c1a6c02e0bc71e33d8d48a66e7c43dce509db Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Fri, 23 Jan 2026 11:06:34 -0600 Subject: [PATCH] Fix frequency calculation for amateur radio regions The frequency calculation for amateur radio regions was incorrectly including `regionInfo.spacing`. This change removes the spacing component from the calculation when the region description contains "Amateur", aligning the behavior with the firmware. --- .../org/meshtastic/core/model/ChannelOption.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/core/model/src/main/kotlin/org/meshtastic/core/model/ChannelOption.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/ChannelOption.kt index 38bc6f5f0..fdd708d8a 100644 --- a/core/model/src/main/kotlin/org/meshtastic/core/model/ChannelOption.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/ChannelOption.kt @@ -99,14 +99,16 @@ internal fun LoRaConfig.radioFreq(channelNum: Int): Float { return if (regionInfo != null) { val bw = bandwidth(regionInfo) val channelSpacing = regionInfo.spacing + bw - // Match firmware: float freq = myRegion->freqStart + myRegion->spacing + (bw / 2000) + (channel_num * + // The frequency calculation attempts to match firmware behavior, + // where channel_num is 0-indexed in the calculation, but 1-indexed in the app's channelNum function. + // For amateur radio regions, regionInfo.spacing is not included in the frequency calculation. + // Firmware example: float freq = myRegion->freqStart + myRegion->spacing + (bw / 2000) + (channel_num * // channelSpacing); - // Note: firmware channel_num is 0-indexed in the calculation, but the app uses 1-indexed for some reason? - // Let's re-verify the firmware logic. - // Firmware: channel_num = hash(channelName) % numChannels; - // freq = myRegion->freqStart + myRegion->spacing + (bw / 2000) + (channel_num * channelSpacing); - // The app's channelNum function returns 1..numChannels if channelNum is 0. - (regionInfo.freqStart + regionInfo.spacing + bw / 2) + (channelNum - 1) * channelSpacing + if (regionInfo.description.contains("Amateur")) { + (regionInfo.freqStart + bw / 2) + (channelNum - 1) * channelSpacing + } else { + (regionInfo.freqStart + regionInfo.spacing + bw / 2) + (channelNum - 1) * channelSpacing + } } else { 0f }