Remove PTT-aware logic, which is not necessary
I was setting the Tx frequency only when we were in Tx mode, but the Icom 705 will accept the command to set the Tx frequency even when in Rx mode, so there is no need to check the PTT state before sending the command.
This commit is contained in:
1 parent
58fb688593
commit
77dfb7bb05
4 files changed
+16
-86
No files matched your search
+4
-23
@@ -151,37 +151,18 @@ class Ic705Controller(
|
||||
}
|
||||
|
||||
override suspend fun pttOn(): Boolean = withContext(Dispatchers.IO) {
|
||||
Log.w(tag, "pttOn: PTT control not used for IC-705 (radio is master)")
|
||||
Log.w(tag, "pttOn: not used for IC-705")
|
||||
true
|
||||
}
|
||||
|
||||
override suspend fun pttOff(): Boolean = withContext(Dispatchers.IO) {
|
||||
Log.w(tag, "pttOff: PTT control not used for IC-705 (radio is master)")
|
||||
Log.w(tag, "pttOff: not used for IC-705")
|
||||
true
|
||||
}
|
||||
|
||||
// ── IRadioController – IC-705 extended operations ───────────────────────
|
||||
|
||||
/**
|
||||
* Read the current PTT (TX/RX) status from the radio.
|
||||
* Returns **true** if the radio is currently transmitting, **false** if
|
||||
* receiving, **null** on error.
|
||||
*/
|
||||
override suspend fun readPttStatus(): Boolean? = withContext(Dispatchers.IO) {
|
||||
ioMutex.withLock {
|
||||
val cmd = IcomCivProtocol.buildReadTxStatusCommand()
|
||||
Log.d(tag, "CMD readPTT → ${IcomCivProtocol.toHex(cmd)}")
|
||||
val payload = sendAndReadResponse(cmd, IcomCivProtocol.CMD_TX_STATUS) ?: return@withContext null
|
||||
IcomCivProtocol.parseTxStatus(payload).also {
|
||||
Log.d(tag, "PTT status: ${if (it == true) "TX" else if (it == false) "RX" else "unknown"}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select VFO-A (main) or VFO-B (sub).
|
||||
* @param vfoA true → VFO-A, false → VFO-B
|
||||
*/
|
||||
/** Select VFO-A (main/RX) or VFO-B (sub/TX). */
|
||||
override suspend fun setVfo(vfoA: Boolean): Boolean = withContext(Dispatchers.IO) {
|
||||
val cmd = if (vfoA) IcomCivProtocol.buildSelectVfoACommand()
|
||||
else IcomCivProtocol.buildSelectVfoBCommand()
|
||||
@@ -212,7 +193,7 @@ class Ic705Controller(
|
||||
|
||||
/**
|
||||
* Set TX VFO frequency via CMD 0x25 sub 0x01 (unselected VFO).
|
||||
* Used in split mode while PTT is pressed.
|
||||
* Sent every tracking cycle in split mode alongside [setWorkingFrequency].
|
||||
*/
|
||||
override suspend fun setTxVfoFrequency(frequencyHz: Long): Boolean = withContext(Dispatchers.IO) {
|
||||
Log.d(tag, "setTxVfoFrequency (0x25/01): ${frequencyHz}Hz")
|
||||
|
||||
+1
-28
@@ -57,9 +57,7 @@ object IcomCivProtocol {
|
||||
const val CMD_CTCSS_TONE: Byte = 0x1B
|
||||
/** Read/write misc settings (used for enabling CTCSS encode). */
|
||||
const val CMD_MISC_SETTING: Byte = 0x16
|
||||
/** Read/write TX-inhibit / transmit status. */
|
||||
const val CMD_TX_STATUS: Byte = 0x1C
|
||||
/** Read/write selected-VFO frequency (cmd 0x25, sub 0x00). */
|
||||
/** Read/write selected-VFO frequency (cmd 0x25). */
|
||||
const val CMD_SELECTED_VFO_FREQ: Byte = 0x25
|
||||
|
||||
// ── Sub-command bytes ──────────────────────────────────────────────────
|
||||
@@ -71,8 +69,6 @@ object IcomCivProtocol {
|
||||
const val SUB_SPLIT_OFF: Byte = 0x00
|
||||
/** Sub for CMD_DUPLEX_SPLIT: SPLIT ON. */
|
||||
const val SUB_SPLIT_ON: Byte = 0x01
|
||||
/** Sub for CMD_TX_STATUS: query TX/RX state. */
|
||||
const val SUB_TX_STATE: Byte = 0x00
|
||||
/** Sub for CMD_SELECTED_VFO_FREQ: selected (active) VFO frequency. */
|
||||
const val SUB_SELECTED_VFO: Byte = 0x00
|
||||
/** Sub for CMD_SELECTED_VFO_FREQ: unselected (inactive / TX in split) VFO frequency. */
|
||||
@@ -200,9 +196,6 @@ object IcomCivProtocol {
|
||||
return frame(CMD_DUPLEX_SPLIT, sub)
|
||||
}
|
||||
|
||||
/** Query TX/RX status (CMD 0x1C sub 0x00). Radio replies with 0x00=RX, 0x01=TX. */
|
||||
fun buildReadTxStatusCommand(): ByteArray = frame(CMD_TX_STATUS, SUB_TX_STATE)
|
||||
|
||||
/**
|
||||
* Enable/disable CTCSS encode (CMD 0x16 sub 0x42).
|
||||
* 0x01 = CTCSS encoder ON, 0x00 = OFF.
|
||||
@@ -293,26 +286,6 @@ object IcomCivProtocol {
|
||||
return freqHz to mode
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse TX status from a CMD_TX_STATUS reply payload.
|
||||
*
|
||||
* The IC-705 responds to a `1C 00` query with:
|
||||
* FE FE E0 A4 1C 00 <status> FD
|
||||
* After [parseResponse] strips the frame header the payload is:
|
||||
* payload[0] = 0x00 (sub-command echo)
|
||||
* payload[1] = status byte (0x00 = RX, 0x01 = TX)
|
||||
*
|
||||
* Returns true if transmitting, false if receiving, null on error.
|
||||
*/
|
||||
fun parseTxStatus(payload: ByteArray): Boolean? {
|
||||
if (payload.size < 2) return null
|
||||
return when (payload[1]) {
|
||||
0x00.toByte() -> false // RX
|
||||
0x01.toByte() -> true // TX
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
/** Hex dump of bytes, useful for debug logging. */
|
||||
fun toHex(bytes: ByteArray): String =
|
||||
bytes.joinToString(" ") { String.format(Locale.US, "%02X", it.toInt() and 0xFF) }
|
||||
|
||||
+8
-24
@@ -380,33 +380,17 @@ class RadioTrackingService(
|
||||
val rxRadioFreq = rxBaseCalc?.let { pos.getDownlinkFreq(it) }
|
||||
|
||||
if (radio.isConnected) {
|
||||
// Query PTT state — don't assume silence; filter broadcast noise
|
||||
val isPtt = radio.readPttStatus()
|
||||
Log.d(tag, "Split loop: isPTT=$isPtt txFreq=$txRadioFreq rxFreq=$rxRadioFreq")
|
||||
|
||||
when (isPtt) {
|
||||
true -> {
|
||||
// PTT ON → radio's active VFO is VFO-B (TX)
|
||||
// Use 0x25/01 (unselected VFO) to target VFO-B directly
|
||||
if (txRadioFreq != null) {
|
||||
Log.d(tag, "Split loop TX update (0x25/01): ${txRadioFreq}Hz")
|
||||
radio.setTxVfoFrequency(txRadioFreq)
|
||||
}
|
||||
// Update both VFOs every cycle — no PTT polling needed.
|
||||
// 0x25/00 = active (RX) VFO, 0x25/01 = inactive (TX) VFO.
|
||||
if (rxRadioFreq != null) {
|
||||
Log.d(tag, "Split loop RX (0x25/00): ${rxRadioFreq}Hz")
|
||||
radio.setWorkingFrequency(rxRadioFreq)
|
||||
}
|
||||
false -> {
|
||||
// PTT OFF → radio's active VFO is VFO-A (RX)
|
||||
// Use 0x25/00 (selected/active VFO) to update RX
|
||||
if (rxRadioFreq != null) {
|
||||
Log.d(tag, "Split loop RX update (0x25/00): ${rxRadioFreq}Hz")
|
||||
radio.setWorkingFrequency(rxRadioFreq)
|
||||
}
|
||||
}
|
||||
null -> {
|
||||
// Could not read PTT (broadcast noise race) — skip this tick
|
||||
Log.d(tag, "Split loop: PTT read failed, skipping tick")
|
||||
if (txRadioFreq != null) {
|
||||
Log.d(tag, "Split loop TX (0x25/01): ${txRadioFreq}Hz")
|
||||
radio.setTxVfoFrequency(txRadioFreq)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_state.update {
|
||||
it.copy(
|
||||
|
||||
+3
-11
@@ -41,13 +41,6 @@ interface IRadioController {
|
||||
|
||||
// ── Extended operations (IC-705 / CI-V) ──────────────────────────────
|
||||
|
||||
/**
|
||||
* Read the current PTT status from the radio.
|
||||
* Returns true if transmitting, false if receiving, null on error.
|
||||
* Default: not supported.
|
||||
*/
|
||||
suspend fun readPttStatus(): Boolean? = null
|
||||
|
||||
/**
|
||||
* Select the active VFO.
|
||||
* @param vfoA true → VFO-A (main/RX), false → VFO-B (sub/TX in split).
|
||||
@@ -62,15 +55,14 @@ interface IRadioController {
|
||||
suspend fun setSplitMode(enabled: Boolean): Boolean = false
|
||||
|
||||
/**
|
||||
* Set the frequency of the currently active VFO (CMD 0x25 sub 0x00).
|
||||
* Set the frequency of the currently active VFO (IC-705: CMD 0x25 sub 0x00).
|
||||
* Default: delegates to [setFrequency].
|
||||
*/
|
||||
suspend fun setWorkingFrequency(frequencyHz: Long): Boolean = setFrequency(frequencyHz)
|
||||
|
||||
/**
|
||||
* Set the frequency of the inactive (TX) VFO via CMD 0x25 sub 0x01.
|
||||
* Used in split mode when PTT is pressed: the radio has made VFO-B
|
||||
* the active VFO, so sub 0x01 targets it directly.
|
||||
* Set the frequency of the inactive/TX VFO (IC-705: CMD 0x25 sub 0x01).
|
||||
* Sent every tracking cycle alongside [setWorkingFrequency] in split mode.
|
||||
* Default: delegates to [setWorkingFrequency].
|
||||
*/
|
||||
suspend fun setTxVfoFrequency(frequencyHz: Long): Boolean = setWorkingFrequency(frequencyHz)
|
||||
|
||||
Reference in new issue
Block a user