Add support for changing operating modes and filters with hotkeys

This commit is contained in:
Nonoo 2020-10-31 14:07:02 +01:00
parent e72fc399ad
commit 65856b23e8
4 changed files with 151 additions and 40 deletions

View file

@ -166,6 +166,9 @@ not available.
- `;`, `'`: decrease, increase frequency 1kHz - `;`, `'`: decrease, increase frequency 1kHz
- `{`, `}`: decrease, increase frequency 10kHz - `{`, `}`: decrease, increase frequency 10kHz
- `[`, `]`: decrease, increase frequency 100kHz - `[`, `]`: decrease, increase frequency 100kHz
- `n`, `m`: cycle through operating modes
- `d`, `f`: cycle through filters
- `D`: toggle data mode
## Authors ## Authors

View file

@ -7,6 +7,35 @@ import (
const civAddress = 0xa4 const civAddress = 0xa4
type civOperatingMode struct {
name string
code byte
}
var civOperatingModes = []civOperatingMode{
{name: "LSB", code: 0x00},
{name: "USB", code: 0x01},
{name: "AM", code: 0x02},
{name: "CW", code: 0x03},
{name: "RTTY", code: 0x04},
{name: "FM", code: 0x05},
{name: "WFM", code: 0x06},
{name: "CW-R", code: 0x07},
{name: "RTTY-R", code: 0x08},
{name: "DV", code: 0x17},
}
type civFilter struct {
name string
code byte
}
var civFilters = []civFilter{
{name: "FIL1", code: 0x01},
{name: "FIL2", code: 0x02},
{name: "FIL3", code: 0x03},
}
type civControlStruct struct { type civControlStruct struct {
st *serialStream st *serialStream
@ -15,6 +44,9 @@ type civControlStruct struct {
ptt bool ptt bool
tune bool tune bool
pwrPercent int pwrPercent int
operatingModeIdx int
filterIdx int
dataMode bool
} }
} }
@ -60,16 +92,13 @@ func (s *civControlStruct) decodeFreq(d []byte) {
statusLog.reportFrequency(s.state.freq) statusLog.reportFrequency(s.state.freq)
} }
func (s *civControlStruct) decodeFilterValue(v byte) string { func (s *civControlStruct) decodeFilterValueToFilterIdx(v byte) int {
switch v { for i := range civFilters {
case 0x01: if civFilters[i].code == v {
return "FIL1" return i
case 0x02:
return "FIL2"
case 0x03:
return "FIL3"
} }
return "" }
return -1
} }
func (s *civControlStruct) decodeMode(d []byte) { func (s *civControlStruct) decodeMode(d []byte) {
@ -78,32 +107,18 @@ func (s *civControlStruct) decodeMode(d []byte) {
} }
var mode string var mode string
switch d[0] { for i := range civOperatingModes {
case 0x00: if civOperatingModes[i].code == d[0] {
mode = "LSB" s.state.operatingModeIdx = i
case 0x01: mode = civOperatingModes[i].name
mode = "USB" break
case 0x02: }
mode = "AM"
case 0x03:
mode = "CW"
case 0x04:
mode = "RTTY"
case 0x05:
mode = "FM"
case 0x06:
mode = "WFM"
case 0x07:
mode = "CW-R"
case 0x08:
mode = "RTTY-R"
case 0x17:
mode = "DV"
} }
var filter string var filter string
if len(d) > 1 { if len(d) > 1 {
filter = s.decodeFilterValue(d[1]) s.state.filterIdx = s.decodeFilterValueToFilterIdx(d[1])
filter = civFilters[s.state.filterIdx].name
} }
statusLog.reportMode(mode, filter) statusLog.reportMode(mode, filter)
@ -120,7 +135,11 @@ func (s *civControlStruct) decodeDataMode(d []byte) {
var filter string var filter string
if d[1] == 1 { if d[1] == 1 {
dataMode = "-D" dataMode = "-D"
filter = s.decodeFilterValue(d[2]) s.state.dataMode = true
s.state.filterIdx = s.decodeFilterValueToFilterIdx(d[2])
filter = civFilters[s.state.filterIdx].name
} else {
s.state.dataMode = false
} }
statusLog.reportDataMode(dataMode, filter) statusLog.reportDataMode(dataMode, filter)
@ -223,6 +242,49 @@ func (s *civControlStruct) setFreq(f float64) error {
return s.getFreq() return s.getFreq()
} }
func (s *civControlStruct) incOperatingMode() error {
s.state.operatingModeIdx++
if s.state.operatingModeIdx >= len(civOperatingModes) {
s.state.operatingModeIdx = 0
}
return civControl.setOperatingModeAndFilter(civOperatingModes[s.state.operatingModeIdx].code,
civFilters[s.state.filterIdx].code)
}
func (s *civControlStruct) decOperatingMode() error {
s.state.operatingModeIdx--
if s.state.operatingModeIdx < 0 {
s.state.operatingModeIdx = len(civOperatingModes) - 1
}
return civControl.setOperatingModeAndFilter(civOperatingModes[s.state.operatingModeIdx].code,
civFilters[s.state.filterIdx].code)
}
func (s *civControlStruct) incFilter() error {
s.state.filterIdx++
if s.state.filterIdx >= len(civFilters) {
s.state.filterIdx = 0
}
return civControl.setOperatingModeAndFilter(civOperatingModes[s.state.operatingModeIdx].code,
civFilters[s.state.filterIdx].code)
}
func (s *civControlStruct) decFilter() error {
s.state.filterIdx--
if s.state.filterIdx < 0 {
s.state.filterIdx = len(civFilters) - 1
}
return civControl.setOperatingModeAndFilter(civOperatingModes[s.state.operatingModeIdx].code,
civFilters[s.state.filterIdx].code)
}
func (s *civControlStruct) setOperatingModeAndFilter(modeCode, filterCode byte) error {
if err := s.st.send([]byte{254, 254, civAddress, 224, 0x06, modeCode, filterCode, 253}); err != nil {
return err
}
return s.getMode()
}
func (s *civControlStruct) setPTT(enable bool) error { func (s *civControlStruct) setPTT(enable bool) error {
var b byte var b byte
if enable { if enable {
@ -245,10 +307,27 @@ func (s *civControlStruct) toggleTune() error {
return s.st.send([]byte{254, 254, civAddress, 224, 0x1c, 1, b, 253}) return s.st.send([]byte{254, 254, civAddress, 224, 0x1c, 1, b, 253})
} }
func (s *civControlStruct) toggleDataMode() error {
var b byte
var f byte
if !s.state.dataMode {
b = 1
f = 1
} else {
b = 0
f = 0
}
return s.st.send([]byte{254, 254, civAddress, 224, 0x1a, 0x06, b, f, 253})
}
func (s *civControlStruct) getFreq() error { func (s *civControlStruct) getFreq() error {
return s.st.send([]byte{254, 254, civAddress, 224, 3, 253}) return s.st.send([]byte{254, 254, civAddress, 224, 3, 253})
} }
func (s *civControlStruct) getMode() error {
return s.st.send([]byte{254, 254, civAddress, 224, 4, 253})
}
func (s *civControlStruct) getDataMode() error { func (s *civControlStruct) getDataMode() error {
return s.st.send([]byte{254, 254, civAddress, 224, 0x1a, 0x06, 253}) return s.st.send([]byte{254, 254, civAddress, 224, 0x1a, 0x06, 253})
} }
@ -266,8 +345,7 @@ func (s *civControlStruct) init(st *serialStream) error {
if err := s.getFreq(); err != nil { if err := s.getFreq(); err != nil {
return err return err
} }
// Querying mode. if err := s.getMode(); err != nil {
if err := s.st.send([]byte{254, 254, civAddress, 224, 4, 253}); err != nil {
return err return err
} }
if err := s.getDataMode(); err != nil { if err := s.getDataMode(); err != nil {

View file

@ -316,8 +316,6 @@ func (s *controlStream) init() error {
return err return err
} }
s.common.pkt7.startPeriodicSend(&s.common, 2, false)
s.common.pkt0.init(&s.common) s.common.pkt0.init(&s.common)
if err := s.sendPktLogin(); err != nil { if err := s.sendPktLogin(); err != nil {
return err return err
@ -344,6 +342,8 @@ func (s *controlStream) init() error {
return errors.New("invalid user/password") return errors.New("invalid user/password")
} }
s.common.pkt7.startPeriodicSend(&s.common, 2, false)
copy(s.authID[:], r[26:32]) copy(s.authID[:], r[26:32])
s.gotAuthID = true s.gotAuthID = true
if err := s.sendPktAuth(0x02); err != nil { if err := s.sendPktAuth(0x02); err != nil {

View file

@ -108,6 +108,36 @@ func (s *keyboardStruct) handleKey(k byte) {
log.Error("can't decrease freq: ", err) log.Error("can't decrease freq: ", err)
} }
} }
case 'm':
if civControl != nil {
if err := civControl.incOperatingMode(); err != nil {
log.Error("can't change mode: ", err)
}
}
case 'n':
if civControl != nil {
if err := civControl.decOperatingMode(); err != nil {
log.Error("can't change mode: ", err)
}
}
case 'f':
if civControl != nil {
if err := civControl.incFilter(); err != nil {
log.Error("can't change filter: ", err)
}
}
case 'd':
if civControl != nil {
if err := civControl.decFilter(); err != nil {
log.Error("can't change filter: ", err)
}
}
case 'D':
if civControl != nil {
if err := civControl.toggleDataMode(); err != nil {
log.Error("can't change datamode: ", err)
}
}
} }
} }