feat: Implemented UDP Outbound Adif message, freq to pstrotator

This commit is contained in:
2026-07-05 18:17:30 +02:00
parent a8b3269b1e
commit 4f32012930
16 changed files with 704 additions and 123 deletions
+62
View File
@@ -45,6 +45,15 @@ const (
CmdATU = 0x1C // sub 0x01 = antenna tuner (0x00 off, 0x01 through, 0x02 tune)
CmdScope = 0x27 // spectrum-scope waveform stream (sub 0x00 = data, 0x11 = on/off)
CmdRIT = 0x21 // RIT/ΔTX: sub 0x00 offset freq, 0x01 RIT on/off, 0x02 ΔTX(XIT) on/off
CmdSendCW = 0x17 // send a CW message (ASCII, ≤30 chars) via the rig's keyer; data 0xFF = stop
SubLevelKeySpeed = 0x0C // CmdLevel: CW keying speed (0-255 → KeyMinWPM..KeyMaxWPM)
// CW keyer speed range for the KEY SPEED level (IC-7610: 6-48 WPM).
KeyMinWPM = 6
KeyMaxWPM = 48
StopCWByte = 0xFF // 0x17 data byte that stops an in-progress CW message
SubRITFreq = 0x00 // RIT/ΔTX offset: 2 BCD bytes (LE, 0-9999) + sign byte (00 +, 01 -)
SubRITOn = 0x01 // RIT on/off (00/01)
@@ -85,6 +94,14 @@ const (
SubSwNB = 0x22 // noise blanker on/off
SubSwNR = 0x40 // noise reduction on/off
SubSwANF = 0x41 // auto-notch on/off
SubSwBreakIn = 0x47 // CW break-in: 0=OFF, 1=SEMI, 2=FULL (needed so 0x17 CW keys TX)
)
// CW break-in modes (CmdSwitch 0x47).
const (
BreakInOff = 0
BreakInSemi = 1
BreakInFull = 2
)
// Icom mode codes (used by CmdReadMode / CmdSetMode).
@@ -191,6 +208,51 @@ func BCDToRIT(b []byte) int {
return v
}
// WPMToKeyLevel maps a CW speed in words-per-minute to the 0-255 value the KEY
// SPEED level (CmdLevel 0x0C) expects, linear across KeyMinWPM..KeyMaxWPM.
func WPMToKeyLevel(wpm int) int {
if wpm < KeyMinWPM {
wpm = KeyMinWPM
}
if wpm > KeyMaxWPM {
wpm = KeyMaxWPM
}
return (wpm - KeyMinWPM) * 255 / (KeyMaxWPM - KeyMinWPM)
}
// KeyLevelToWPM is the inverse of WPMToKeyLevel (0-255 → WPM).
func KeyLevelToWPM(v int) int {
if v < 0 {
v = 0
}
if v > 255 {
v = 255
}
return KeyMinWPM + (v*(KeyMaxWPM-KeyMinWPM)+127)/255
}
// CWText is the set of characters the rig's keyer accepts (command 0x17).
// Everything else is dropped. Space keys a word gap.
const CWText = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 /?.,-=+@:"
// FilterCW upper-cases text and keeps only keyer-legal characters.
func FilterCW(text string) string {
out := make([]byte, 0, len(text))
for i := 0; i < len(text); i++ {
c := text[i]
if c >= 'a' && c <= 'z' {
c -= 32
}
for j := 0; j < len(CWText); j++ {
if CWText[j] == c {
out = append(out, c)
break
}
}
}
return string(out)
}
// ByteToBCD / BCDToByte handle a single packed-BCD byte (used by the
// attenuator, where the value is dB: 0x00, 0x06, 0x12, 0x18…).
func ByteToBCD(v int) byte {