From c99f50575d100fc835f407f587fa3830370d63f9 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 1 Jul 2020 13:02:14 +0100 Subject: [PATCH] Add a simpe simplex FM controller state machine. --- FM.cpp | 163 +++++++++++++++++++++++++++++++++++++++++++-------------- FM.h | 31 ++++++----- 2 files changed, 142 insertions(+), 52 deletions(-) diff --git a/FM.cpp b/FM.cpp index 980b0fc..907ad5e 100644 --- a/FM.cpp +++ b/FM.cpp @@ -117,14 +117,24 @@ void CFM::samples(bool cos, q15_t* samples, uint8_t length) } // Only let RF audio through when relaying RF audio - if (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF || m_state == FS_RELAYING_EXT || m_state == FS_KERCHUNK_EXT) { - currentSample = m_blanking.process(currentSample); - if (m_extEnabled && (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF)) - m_downSampler.addSample(currentSample); + if (m_duplex) { + if (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF || m_state == FS_RELAYING_EXT || m_state == FS_KERCHUNK_EXT) { + currentSample = m_blanking.process(currentSample); + if (m_extEnabled && (m_state == FS_RELAYING_RF || m_state == FS_KERCHUNK_RF)) + m_downSampler.addSample(currentSample); - currentSample *= currentBoost; + currentSample *= currentBoost; + } else { + currentSample = 0; + } } else { - currentSample = 0; + if (m_state == FS_RELAYING_EXT) { + currentSample *= currentBoost; + } else { + if (m_extEnabled && m_state == FS_RELAYING_RF) + m_downSampler.addSample(currentSample); + return; + } } if (!m_callsign.isRunning() && !m_extAck.isRunning()) @@ -281,43 +291,73 @@ uint8_t CFM::setExt(const char* ack, uint8_t audioBoost, uint8_t speed, uint16_t } void CFM::stateMachine(bool validRFSignal, bool validExtSignal) +{ + if (m_duplex) + duplexStateMachine(validRFSignal, validExtSignal); + else + simplexStateMachine(validRFSignal, validExtSignal); +} + +void CFM::simplexStateMachine(bool validRFSignal, bool validExtSignal) { switch (m_state) { case FS_LISTENING: - listeningState(validRFSignal, validExtSignal); - break; - case FS_KERCHUNK_RF: - kerchunkRFState(validRFSignal); + listeningStateSimplex(validRFSignal, validExtSignal); break; case FS_RELAYING_RF: - relayingRFState(validRFSignal); - break; - case FS_RELAYING_WAIT_RF: - relayingRFWaitState(validRFSignal); - break; - case FS_TIMEOUT_RF: - timeoutRFState(validRFSignal); - break; - case FS_TIMEOUT_WAIT_RF: - timeoutRFWaitState(validRFSignal); - break; - case FS_KERCHUNK_EXT: - kerchunkExtState(validExtSignal); + relayingRFStateSimplex(validRFSignal); break; case FS_RELAYING_EXT: - relayingExtState(validExtSignal); + relayingExtStateSimplex(validExtSignal); + break; + default: + break; + } + + if (m_state == FS_LISTENING) { + m_outputRFRB.reset(); + m_downSampler.reset(); + } +} + +void CFM::duplexStateMachine(bool validRFSignal, bool validExtSignal) +{ + switch (m_state) { + case FS_LISTENING: + listeningStateDuplex(validRFSignal, validExtSignal); + break; + case FS_KERCHUNK_RF: + kerchunkRFStateDuplex(validRFSignal); + break; + case FS_RELAYING_RF: + relayingRFStateDuplex(validRFSignal); + break; + case FS_RELAYING_WAIT_RF: + relayingRFWaitStateDuplex(validRFSignal); + break; + case FS_TIMEOUT_RF: + timeoutRFStateDuplex(validRFSignal); + break; + case FS_TIMEOUT_WAIT_RF: + timeoutRFWaitStateDuplex(validRFSignal); + break; + case FS_KERCHUNK_EXT: + kerchunkExtStateDuplex(validExtSignal); + break; + case FS_RELAYING_EXT: + relayingExtStateDuplex(validExtSignal); break; case FS_RELAYING_WAIT_EXT: - relayingExtWaitState(validExtSignal); + relayingExtWaitStateDuplex(validExtSignal); break; case FS_TIMEOUT_EXT: - timeoutExtState(validExtSignal); + timeoutExtStateDuplex(validExtSignal); break; case FS_TIMEOUT_WAIT_EXT: - timeoutExtWaitState(validExtSignal); + timeoutExtWaitStateDuplex(validExtSignal); break; case FS_HANG: - hangState(validRFSignal, validExtSignal); + hangStateDuplex(validRFSignal, validExtSignal); break; default: break; @@ -346,7 +386,7 @@ void CFM::clock(uint8_t length) } } -void CFM::listeningState(bool validRFSignal, bool validExtSignal) +void CFM::listeningStateDuplex(bool validRFSignal, bool validExtSignal) { if (validRFSignal) { if (m_kerchunkTimer.getTimeout() > 0U) { @@ -402,7 +442,27 @@ void CFM::listeningState(bool validRFSignal, bool validExtSignal) } } -void CFM::kerchunkRFState(bool validSignal) +void CFM::listeningStateSimplex(bool validRFSignal, bool validExtSignal) +{ + if (validRFSignal) { + DEBUG1("State to RELAYING_RF"); + m_state = FS_RELAYING_RF; + + io.setDecode(true); + io.setADCDetection(true); + + m_statusTimer.start(); + serial.writeFMStatus(m_state); + } else if (validExtSignal) { + DEBUG1("State to RELAYING_EXT"); + m_state = FS_RELAYING_EXT; + + m_statusTimer.start(); + serial.writeFMStatus(m_state); + } +} + +void CFM::kerchunkRFStateDuplex(bool validSignal) { if (validSignal) { if (m_kerchunkTimer.hasExpired()) { @@ -444,7 +504,7 @@ void CFM::kerchunkRFState(bool validSignal) } } -void CFM::relayingRFState(bool validSignal) +void CFM::relayingRFStateDuplex(bool validSignal) { if (validSignal) { if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) { @@ -475,7 +535,22 @@ void CFM::relayingRFState(bool validSignal) } } -void CFM::relayingRFWaitState(bool validSignal) +void CFM::relayingRFStateSimplex(bool validSignal) +{ + if (!validSignal) { + io.setDecode(false); + io.setADCDetection(false); + + DEBUG1("State to LISTENING"); + m_state = FS_LISTENING; + m_ackDelayTimer.start(); + + if (m_extEnabled) + serial.writeFMEOT(); + } +} + +void CFM::relayingRFWaitStateDuplex(bool validSignal) { if (validSignal) { io.setDecode(true); @@ -513,7 +588,7 @@ void CFM::relayingRFWaitState(bool validSignal) } } -void CFM::kerchunkExtState(bool validSignal) +void CFM::kerchunkExtStateDuplex(bool validSignal) { if (validSignal) { if (m_kerchunkTimer.hasExpired()) { @@ -546,7 +621,7 @@ void CFM::kerchunkExtState(bool validSignal) } } -void CFM::relayingExtState(bool validSignal) +void CFM::relayingExtStateDuplex(bool validSignal) { if (validSignal) { if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) { @@ -568,7 +643,15 @@ void CFM::relayingExtState(bool validSignal) } } -void CFM::relayingExtWaitState(bool validSignal) +void CFM::relayingExtStateSimplex(bool validSignal) +{ + if (!validSignal) { + DEBUG1("State to LISTENING"); + m_state = FS_LISTENING; + } +} + +void CFM::relayingExtWaitStateDuplex(bool validSignal) { if (validSignal) { DEBUG1("State to RELAYING_EXT"); @@ -603,7 +686,7 @@ void CFM::relayingExtWaitState(bool validSignal) } } -void CFM::hangState(bool validRFSignal, bool validExtSignal) +void CFM::hangStateDuplex(bool validRFSignal, bool validExtSignal) { if (validRFSignal) { io.setDecode(true); @@ -643,7 +726,7 @@ void CFM::hangState(bool validRFSignal, bool validExtSignal) } } -void CFM::timeoutRFState(bool validSignal) +void CFM::timeoutRFStateDuplex(bool validSignal) { if (!validSignal) { io.setDecode(false); @@ -664,7 +747,7 @@ void CFM::timeoutRFState(bool validSignal) } } -void CFM::timeoutRFWaitState(bool validSignal) +void CFM::timeoutRFWaitStateDuplex(bool validSignal) { if (validSignal) { io.setDecode(true); @@ -693,7 +776,7 @@ void CFM::timeoutRFWaitState(bool validSignal) } } -void CFM::timeoutExtState(bool validSignal) +void CFM::timeoutExtStateDuplex(bool validSignal) { if (!validSignal) { DEBUG1("State to TIMEOUT_WAIT_EXT"); @@ -707,7 +790,7 @@ void CFM::timeoutExtState(bool validSignal) } } -void CFM::timeoutExtWaitState(bool validSignal) +void CFM::timeoutExtWaitStateDuplex(bool validSignal) { if (validSignal) { DEBUG1("State to TIMEOUT_EXT"); diff --git a/FM.h b/FM.h index a6a37a8..58ca5a9 100644 --- a/FM.h +++ b/FM.h @@ -103,18 +103,25 @@ private: CFMUpSampler m_inputExtRB; void stateMachine(bool validRFSignal, bool validExtSignal); - void listeningState(bool validRFSignal, bool validExtSignal); - void kerchunkRFState(bool validSignal); - void relayingRFState(bool validSignal); - void relayingRFWaitState(bool validSignal); - void timeoutRFState(bool validSignal); - void timeoutRFWaitState(bool validSignal); - void kerchunkExtState(bool validSignal); - void relayingExtState(bool validSignal); - void relayingExtWaitState(bool validSignal); - void timeoutExtState(bool validSignal); - void timeoutExtWaitState(bool validSignal); - void hangState(bool validRFSignal, bool validExtSignal); + + void duplexStateMachine(bool validRFSignal, bool validExtSignal); + void listeningStateDuplex(bool validRFSignal, bool validExtSignal); + void kerchunkRFStateDuplex(bool validSignal); + void relayingRFStateDuplex(bool validSignal); + void relayingRFWaitStateDuplex(bool validSignal); + void timeoutRFStateDuplex(bool validSignal); + void timeoutRFWaitStateDuplex(bool validSignal); + void kerchunkExtStateDuplex(bool validSignal); + void relayingExtStateDuplex(bool validSignal); + void relayingExtWaitStateDuplex(bool validSignal); + void timeoutExtStateDuplex(bool validSignal); + void timeoutExtWaitStateDuplex(bool validSignal); + void hangStateDuplex(bool validRFSignal, bool validExtSignal); + + void simplexStateMachine(bool validRFSignal, bool validExtSignal); + void listeningStateSimplex(bool validRFSignal, bool validExtSignal); + void relayingRFStateSimplex(bool validSignal); + void relayingExtStateSimplex(bool validSignal); void clock(uint8_t length);