From 5056437bb337ac7cffb1fa2e5f99562ccab48fe4 Mon Sep 17 00:00:00 2001 From: Nonoo Date: Sat, 7 Nov 2020 18:09:09 +0100 Subject: [PATCH] Add split/DUP+- toggle support --- README.md | 1 + civcontrol.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ hotkeys.go | 6 +++++ statuslog.go | 24 +++++++++++++++++++- 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 52f7258..6a67397 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,7 @@ Some basic CAT control hotkeys are also supported: - `p`: toggles preamp - `a`: toggles AGC - `o`: toggles VFO A/B +- `s`: toggles split/DUP+- operation ## Icom IC-705 Wi-Fi notes diff --git a/civcontrol.go b/civcontrol.go index c2059fd..5eb3261 100644 --- a/civcontrol.go +++ b/civcontrol.go @@ -64,6 +64,15 @@ var civBands = []civBand{ {freqFrom: 0, freqTo: 0}, // GENE } +type splitMode int + +const ( + splitModeOff = iota + splitModeOn + splitModeDUPMinus + splitModeDUPPlus +) + type civControlStruct struct { st *serialStream deinitNeeded chan bool @@ -98,6 +107,7 @@ type civControlStruct struct { setNREnabledSent bool setTSSent bool setVFOSent bool + setSplitSent bool freq uint ptt bool @@ -117,6 +127,7 @@ type civControlStruct struct { tsValue byte ts uint vfoBActive bool + splitMode splitMode } } @@ -145,6 +156,8 @@ func (s *civControlStruct) decode(d []byte) bool { return s.decodeMode(payload) case 0x07: return s.decodeVFO(payload) + case 0x0f: + return s.decodeSplit(payload) case 0x10: return s.decodeTS(payload) case 0x1a: @@ -264,6 +277,34 @@ func (s *civControlStruct) decodeVFO(d []byte) bool { return true } +func (s *civControlStruct) decodeSplit(d []byte) bool { + if len(d) < 1 { + return !s.state.setSplitSent + } + + var str string + switch d[0] { + default: + s.state.splitMode = splitModeOff + case 0x01: + s.state.splitMode = splitModeOn + str = "SPLIT" + case 0x11: + s.state.splitMode = splitModeDUPMinus + str = "DUP-" + case 0x12: + s.state.splitMode = splitModeDUPPlus + str = "DUP+" + } + statusLog.reportSplit(str) + + if s.state.setSplitSent { + s.state.setSplitSent = false + return false + } + return true +} + func (s *civControlStruct) decodeTS(d []byte) bool { if len(d) < 1 { return !s.state.setTSSent @@ -856,6 +897,22 @@ func (s *civControlStruct) toggleVFO() error { return s.st.send([]byte{254, 254, civAddress, 224, 0x07, b, 253}) } +func (s *civControlStruct) toggleSplit() error { + s.state.setSplitSent = true + var b byte + switch s.state.splitMode { + case splitModeOff: + b = 0x01 + case splitModeOn: + b = 0x011 + case splitModeDUPMinus: + b = 0x12 + default: + b = 0x10 + } + return s.st.send([]byte{254, 254, civAddress, 224, 0x0f, b, 253}) +} + func (s *civControlStruct) getFreq() error { s.state.getFreqSent = true return s.st.send([]byte{254, 254, civAddress, 224, 3, 253}) @@ -994,6 +1051,10 @@ func (s *civControlStruct) init(st *serialStream) error { if err := s.getNREnabled(); err != nil { return err } + // Querying split. + if err := s.st.send([]byte{254, 254, civAddress, 224, 0x0f, 253}); err != nil { + return err + } s.deinitNeeded = make(chan bool) s.deinitFinished = make(chan bool) diff --git a/hotkeys.go b/hotkeys.go index 15fc445..7c7e847 100644 --- a/hotkeys.go +++ b/hotkeys.go @@ -218,6 +218,12 @@ func handleHotkey(k byte) { log.Error("can't change vfo: ", err) } } + case 's': + if civControl != nil { + if err := civControl.toggleSplit(); err != nil { + log.Error("can't change split: ", err) + } + } case '\n': if statusLog.isRealtime() { statusLog.mutex.Lock() diff --git a/statuslog.go b/statuslog.go index 179c6c7..a79ad52 100644 --- a/statuslog.go +++ b/statuslog.go @@ -33,6 +33,7 @@ type statusLogData struct { ovf bool swr string ts string + split string startTime time.Time rttStr string @@ -52,6 +53,7 @@ type statusLogStruct struct { rxColor *color.Color retransmitsColor *color.Color lostColor *color.Color + splitColor *color.Color stateStr struct { tx string @@ -289,6 +291,20 @@ func (s *statusLogStruct) reportNR(percent int) { s.data.nr = fmt.Sprint(percent, "%") } +func (s *statusLogStruct) reportSplit(split string) { + s.mutex.Lock() + defer s.mutex.Unlock() + + if s.data == nil { + return + } + if split == "" { + s.data.split = "" + } else { + s.data.split = s.preGenerated.splitColor.Sprint(split) + } +} + func (s *statusLogStruct) clearInternal() { fmt.Printf("%c[2K", 27) } @@ -399,12 +415,16 @@ func (s *statusLogStruct) update() { if s.data.txPower != "" { txPowerStr = " txpwr " + s.data.txPower } + var splitStr string + if s.data.split != "" { + splitStr = " " + s.data.split + } var swrStr string if (s.data.tune || s.data.ptt) && s.data.swr != "" { swrStr = " SWR" + s.data.swr } s.data.line2 = fmt.Sprint(stateStr, " ", fmt.Sprintf("%.6f", float64(s.data.frequency)/1000000), - tsStr, modeStr, vdStr, txPowerStr, swrStr) + tsStr, modeStr, splitStr, vdStr, txPowerStr, swrStr) up, down, lost, retransmits := netstat.get() lostStr := "0" @@ -530,4 +550,6 @@ func (s *statusLogStruct) initIfNeeded() { s.preGenerated.retransmitsColor.Add(color.BgYellow) s.preGenerated.lostColor = color.New(color.FgHiWhite) s.preGenerated.lostColor.Add(color.BgRed) + + s.preGenerated.splitColor = color.New(color.FgHiMagenta) }