Add i and I rigctld commands

This commit is contained in:
Nonoo 2020-11-09 11:00:00 +01:00
parent 4b5e185da5
commit ad03d096cc
3 changed files with 157 additions and 54 deletions

View file

@ -112,31 +112,35 @@ type civControlStruct struct {
getNR civCmd
getNREnabled civCmd
getSplit civCmd
getMainVFOFreq civCmd
getSubVFOFreq civCmd
lastSReceivedAt time.Time
lastOVFReceivedAt time.Time
lastSWRReceivedAt time.Time
setPwr civCmd
setRFGain civCmd
setSQL civCmd
setNR civCmd
setFreq civCmd
setMode civCmd
setPTT civCmd
setTune civCmd
setDataMode civCmd
setPreamp civCmd
setAGC civCmd
setNREnabled civCmd
setTS civCmd
setVFO civCmd
setSplit civCmd
setPwr civCmd
setRFGain civCmd
setSQL civCmd
setNR civCmd
setFreq civCmd
setSubVFOFreq civCmd
setMode civCmd
setPTT civCmd
setTune civCmd
setDataMode civCmd
setPreamp civCmd
setAGC civCmd
setNREnabled civCmd
setTS civCmd
setVFO civCmd
setSplit civCmd
pttTimeoutTimer *time.Timer
tuneTimeoutTimer *time.Timer
freq uint
subFreq uint
ptt bool
tune bool
pwrPercent int
@ -200,16 +204,13 @@ func (s *civControlStruct) decode(d []byte) bool {
return s.decodeVdSWRS(payload)
case 0x16:
return s.decodePreampAGCNREnabled(payload)
case 0x25:
return s.decodeVFOFreq(payload)
}
return true
}
func (s *civControlStruct) decodeFreq(d []byte) bool {
if len(d) < 2 {
return !s.state.getFreq.pending && !s.state.setFreq.pending
}
var f uint
func (s *civControlStruct) decodeFreqData(d []byte) (f uint) {
var pos int
for _, v := range d {
s1 := v & 0x0f
@ -219,8 +220,15 @@ func (s *civControlStruct) decodeFreq(d []byte) bool {
f += uint(s2) * uint(math.Pow(10, float64(pos)))
pos++
}
return
}
s.state.freq = f
func (s *civControlStruct) decodeFreq(d []byte) bool {
if len(d) < 2 {
return !s.state.getFreq.pending && !s.state.setFreq.pending
}
s.state.freq = s.decodeFreqData(d)
statusLog.reportFrequency(s.state.freq)
s.state.bandIdx = len(civBands) - 1 // Set the band idx to GENE by default.
@ -298,9 +306,8 @@ func (s *civControlStruct) decodeVFO(d []byte) bool {
}
if s.state.setVFO.pending {
// The radio does not send the VFO's frequency automatically.
_ = s.getFreq()
// The radio does not send frequencies automatically.
_ = s.getBothVFOFreq()
s.removePendingCmd(&s.state.setVFO)
return false
}
@ -326,7 +333,7 @@ func (s *civControlStruct) decodeSplit(d []byte) bool {
s.state.splitMode = splitModeDUPPlus
str = "DUP+"
}
statusLog.reportSplit(str)
statusLog.reportSplit(s.state.splitMode, str)
if s.state.getSplit.pending {
s.removePendingCmd(&s.state.getSplit)
@ -683,6 +690,45 @@ func (s *civControlStruct) decodePreampAGCNREnabled(d []byte) bool {
return true
}
func (s *civControlStruct) decodeVFOFreq(d []byte) bool {
if len(d) < 2 {
return !s.state.getMainVFOFreq.pending && !s.state.getSubVFOFreq.pending && !s.state.setSubVFOFreq.pending
}
f := s.decodeFreqData(d[1:])
switch d[0] {
default:
s.state.freq = f
statusLog.reportFrequency(s.state.freq)
s.state.bandIdx = len(civBands) - 1 // Set the band idx to GENE by default.
for i := range civBands {
if s.state.freq >= civBands[i].freqFrom && s.state.freq <= civBands[i].freqTo {
s.state.bandIdx = i
civBands[s.state.bandIdx].freq = s.state.freq
break
}
}
if s.state.getMainVFOFreq.pending {
s.removePendingCmd(&s.state.getMainVFOFreq)
return false
}
case 0x01:
s.state.subFreq = f
statusLog.reportSubFrequency(s.state.subFreq)
if s.state.getSubVFOFreq.pending {
s.removePendingCmd(&s.state.getSubVFOFreq)
return false
}
if s.state.setSubVFOFreq.pending {
s.removePendingCmd(&s.state.setSubVFOFreq)
return false
}
}
return true
}
func (s *civControlStruct) initCmd(cmd *civCmd, name string, data []byte) {
*cmd = civCmd{}
cmd.name = name
@ -828,8 +874,7 @@ func (s *civControlStruct) decFreq() error {
return s.setFreq(s.state.freq - s.state.ts)
}
func (s *civControlStruct) setFreq(f uint) error {
var b [5]byte
func (s *civControlStruct) encodeFreqData(f uint) (b [5]byte) {
v0 := s.getDigit(f, 9)
v1 := s.getDigit(f, 8)
b[4] = v0<<4 | v1
@ -845,10 +890,21 @@ func (s *civControlStruct) setFreq(f uint) error {
v0 = s.getDigit(f, 1)
v1 = s.getDigit(f, 0)
b[0] = v0<<4 | v1
return
}
func (s *civControlStruct) setFreq(f uint) error {
b := s.encodeFreqData(f)
s.initCmd(&s.state.setFreq, "setFreq", []byte{254, 254, civAddress, 224, 5, b[0], b[1], b[2], b[3], b[4], 253})
return s.sendCmd(&s.state.setFreq)
}
func (s *civControlStruct) setSubVFOFreq(f uint) error {
b := s.encodeFreqData(f)
s.initCmd(&s.state.setSubVFOFreq, "setSubVFOFreq", []byte{254, 254, civAddress, 224, 0x25, 0x01, b[0], b[1], b[2], b[3], b[4], 253})
return s.sendCmd(&s.state.setSubVFOFreq)
}
func (s *civControlStruct) incOperatingMode() error {
s.state.operatingModeIdx++
if s.state.operatingModeIdx >= len(civOperatingModes) {
@ -1067,10 +1123,10 @@ func (s *civControlStruct) toggleSplit() error {
return s.setSplit(mode)
}
func (s *civControlStruct) getFreq() error {
s.initCmd(&s.state.getFreq, "getFreq", []byte{254, 254, civAddress, 224, 3, 253})
return s.sendCmd(&s.state.getFreq)
}
// func (s *civControlStruct) getFreq() error {
// s.initCmd(&s.state.getFreq, "getFreq", []byte{254, 254, civAddress, 224, 3, 253})
// return s.sendCmd(&s.state.getFreq)
// }
func (s *civControlStruct) getMode() error {
s.initCmd(&s.state.getMode, "getMode", []byte{254, 254, civAddress, 224, 4, 253})
@ -1156,6 +1212,15 @@ func (s *civControlStruct) getSplit() error {
return s.sendCmd(&s.state.getSplit)
}
func (s *civControlStruct) getBothVFOFreq() error {
s.initCmd(&s.state.getMainVFOFreq, "getMainVFOFreq", []byte{254, 254, civAddress, 224, 0x25, 0, 253})
if err := s.sendCmd(&s.state.getMainVFOFreq); err != nil {
return err
}
s.initCmd(&s.state.getSubVFOFreq, "getSubVFOFreq", []byte{254, 254, civAddress, 224, 0x25, 1, 253})
return s.sendCmd(&s.state.getSubVFOFreq)
}
func (s *civControlStruct) loop() {
for {
s.state.mutex.Lock()
@ -1205,7 +1270,7 @@ func (s *civControlStruct) loop() {
func (s *civControlStruct) init(st *serialStream) error {
s.st = st
if err := s.getFreq(); err != nil {
if err := s.getBothVFOFreq(); err != nil {
return err
}
if err := s.getMode(); err != nil {
@ -1256,6 +1321,9 @@ func (s *civControlStruct) init(st *serialStream) error {
if err := s.getSplit(); err != nil {
return err
}
if err := s.getBothVFOFreq(); err != nil {
return err
}
s.deinitNeeded = make(chan bool)
s.deinitFinished = make(chan bool)

View file

@ -270,6 +270,24 @@ func (s *rigctldStruct) processCmd(cmd string) (close bool, err error) {
} else {
_ = s.sendReplyCode(rigctldNoError)
}
case cmd == "i":
civControl.state.mutex.Lock()
defer civControl.state.mutex.Unlock()
err = s.send(civControl.state.subFreq, "\n")
case cmdSplit[0] == "I":
var f float64
f, err = strconv.ParseFloat(cmdSplit[1], 0)
if err != nil {
_ = s.sendReplyCode(rigctldInvalidParam)
return
}
err = civControl.setSubVFOFreq(uint(f))
if err != nil {
_ = s.sendReplyCode(rigctldInvalidParam)
return
}
err = s.sendReplyCode(rigctldNoError)
case cmd == "v": // Ignore this command.
_ = s.sendReplyCode(rigctldUnsupportedCmd)
return

View file

@ -15,25 +15,27 @@ type statusLogData struct {
line2 string
line3 string
ptt bool
tune bool
frequency uint
mode string
dataMode string
filter string
preamp string
agc string
vd string
txPower string
rfGain string
sql string
nr string
nrEnabled bool
s string
ovf bool
swr string
ts string
split string
ptt bool
tune bool
frequency uint
subFrequency uint
mode string
dataMode string
filter string
preamp string
agc string
vd string
txPower string
rfGain string
sql string
nr string
nrEnabled bool
s string
ovf bool
swr string
ts string
split string
splitMode splitMode
startTime time.Time
rttStr string
@ -125,6 +127,16 @@ func (s *statusLogStruct) reportFrequency(f uint) {
s.data.frequency = f
}
func (s *statusLogStruct) reportSubFrequency(f uint) {
s.mutex.Lock()
defer s.mutex.Unlock()
if s.data == nil {
return
}
s.data.subFrequency = f
}
func (s *statusLogStruct) reportMode(mode, filter string) {
s.mutex.Lock()
defer s.mutex.Unlock()
@ -291,13 +303,14 @@ func (s *statusLogStruct) reportNR(percent int) {
s.data.nr = fmt.Sprint(percent, "%")
}
func (s *statusLogStruct) reportSplit(split string) {
func (s *statusLogStruct) reportSplit(mode splitMode, split string) {
s.mutex.Lock()
defer s.mutex.Unlock()
if s.data == nil {
return
}
s.data.splitMode = mode
if split == "" {
s.data.split = ""
} else {
@ -419,12 +432,16 @@ func (s *statusLogStruct) update() {
if s.data.split != "" {
splitStr = " " + s.data.split
}
var subFreqStr string
if s.data.splitMode == splitModeOn {
subFreqStr = fmt.Sprintf("/%.6f", float64(s.data.subFrequency)/1000000)
}
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, splitStr, vdStr, txPowerStr, swrStr)
tsStr, modeStr, splitStr, subFreqStr, vdStr, txPowerStr, swrStr)
up, down, lost, retransmits := netstat.get()
lostStr := "0"