diff --git a/FM.cpp b/FM.cpp index 0cd9494..35e3052 100644 --- a/FM.cpp +++ b/FM.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020,2021 by Jonathan Naylor G4KLX + * Copyright (C) 2020,2021,2023 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +28,19 @@ const uint16_t FM_SERIAL_BLOCK_SIZE = 80U;//this is the number of sample pairs t //three times this value shall never exceed 252 const uint16_t FM_SERIAL_BLOCK_SIZE_BYTES = FM_SERIAL_BLOCK_SIZE * 3U; +const uint8_t FS_LISTENING = 0U; +const uint8_t FS_KERCHUNK_RF = 1U; +const uint8_t FS_RELAYING_RF = 2U; +const uint8_t FS_RELAYING_WAIT_RF = 3U; +const uint8_t FS_TIMEOUT_RF = 4U; +const uint8_t FS_TIMEOUT_WAIT_RF = 5U; +const uint8_t FS_KERCHUNK_EXT = 6U; +const uint8_t FS_RELAYING_EXT = 7U; +const uint8_t FS_RELAYING_WAIT_EXT = 8U; +const uint8_t FS_TIMEOUT_EXT = 9U; +const uint8_t FS_TIMEOUT_WAIT_EXT = 10U; +const uint8_t FS_HANG = 11U; + CFM::CFM() : m_callsign(), @@ -48,7 +61,6 @@ m_kerchunkTimer(), m_ackMinTimer(), m_ackDelayTimer(), m_hangTimer(), -m_statusTimer(), m_reverseTimer(), m_needReverse(false), m_filterStage1( 724, 1448, 724, 32768, -37895, 21352),//3rd order Cheby Filter 300 to 2700Hz, 0.2dB passband ripple, sampling rate 24kHz @@ -70,7 +82,6 @@ m_inputExtRB(), m_rfSignal(false), m_extSignal(false) { - m_statusTimer.setTimeout(1U, 0U); m_reverseTimer.setTimeout(0U, 150U); insertDelay(100U); @@ -370,6 +381,7 @@ void CFM::process() void CFM::reset() { m_state = FS_LISTENING; + serial.writeFMStatus(m_state); m_callsignTimer.stop(); m_timeoutTimer.stop(); @@ -377,7 +389,6 @@ void CFM::reset() m_ackMinTimer.stop(); m_ackDelayTimer.stop(); m_hangTimer.stop(); - m_statusTimer.stop(); m_reverseTimer.stop(); m_ctcssRX.reset(); @@ -583,13 +594,7 @@ void CFM::clock(uint8_t length) m_ackMinTimer.clock(length); m_ackDelayTimer.clock(length); m_hangTimer.clock(length); - m_statusTimer.clock(length); m_reverseTimer.clock(length); - - if (m_statusTimer.isRunning() && m_statusTimer.hasExpired()) { - serial.writeFMStatus(m_state); - m_statusTimer.start(); - } } void CFM::listeningStateDuplex(bool validRFSignal, bool validExtSignal) @@ -598,12 +603,16 @@ void CFM::listeningStateDuplex(bool validRFSignal, bool validExtSignal) if (m_kerchunkTimer.getTimeout() > 0U) { DEBUG1("State to KERCHUNK_RF"); m_state = FS_KERCHUNK_RF; + serial.writeFMStatus(m_state); + m_kerchunkTimer.start(); if (m_callsignAtStart && !m_callsignAtLatch) sendCallsign(); } else { DEBUG1("State to RELAYING_RF"); m_state = FS_RELAYING_RF; + serial.writeFMStatus(m_state); + if (m_callsignAtStart) sendCallsign(); } @@ -618,20 +627,21 @@ void CFM::listeningStateDuplex(bool validRFSignal, bool validExtSignal) io.setDecode(true); io.setADCDetection(true); - - m_statusTimer.start(); - serial.writeFMStatus(m_state); } } else if (validExtSignal) { if (m_kerchunkTimer.getTimeout() > 0U) { DEBUG1("State to KERCHUNK_EXT"); m_state = FS_KERCHUNK_EXT; + serial.writeFMStatus(m_state); + m_kerchunkTimer.start(); if (m_callsignAtStart && !m_callsignAtLatch) sendCallsign(); } else { DEBUG1("State to RELAYING_EXT"); m_state = FS_RELAYING_EXT; + serial.writeFMStatus(m_state); + if (m_callsignAtStart) sendCallsign(); } @@ -643,9 +653,6 @@ void CFM::listeningStateDuplex(bool validRFSignal, bool validExtSignal) m_callsignTimer.start(); m_reverseTimer.stop(); - - m_statusTimer.start(); - serial.writeFMStatus(m_state); } } } @@ -655,26 +662,22 @@ void CFM::listeningStateSimplex(bool validRFSignal, bool validExtSignal) if (validRFSignal) { DEBUG1("State to RELAYING_RF"); m_state = FS_RELAYING_RF; + serial.writeFMStatus(m_state); io.setDecode(true); io.setADCDetection(true); m_timeoutTimer.start(); m_reverseTimer.stop(); - - m_statusTimer.start(); - serial.writeFMStatus(m_state); } else if (validExtSignal) { DEBUG1("State to RELAYING_EXT"); m_state = FS_RELAYING_EXT; + serial.writeFMStatus(m_state); insertSilence(50U); m_timeoutTimer.start(); m_reverseTimer.stop(); - - m_statusTimer.start(); - serial.writeFMStatus(m_state); } } @@ -684,6 +687,8 @@ void CFM::kerchunkRFStateDuplex(bool validSignal) if (m_kerchunkTimer.hasExpired()) { DEBUG1("State to RELAYING_RF"); m_state = FS_RELAYING_RF; + serial.writeFMStatus(m_state); + m_kerchunkTimer.stop(); if (m_callsignAtStart && m_callsignAtLatch) { sendCallsign(); @@ -696,11 +701,12 @@ void CFM::kerchunkRFStateDuplex(bool validSignal) DEBUG1("State to LISTENING"); m_state = FS_LISTENING; + serial.writeFMStatus(m_state); + m_kerchunkTimer.stop(); m_timeoutTimer.stop(); m_ackMinTimer.stop(); m_callsignTimer.stop(); - m_statusTimer.stop(); m_needReverse = true; if (m_extEnabled) serial.writeFMEOT(); @@ -713,6 +719,8 @@ void CFM::relayingRFStateDuplex(bool validSignal) if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) { DEBUG1("State to TIMEOUT_RF"); m_state = FS_TIMEOUT_RF; + serial.writeFMStatus(m_state); + m_ackMinTimer.stop(); m_timeoutTimer.stop(); m_timeoutTone.start(); @@ -726,6 +734,8 @@ void CFM::relayingRFStateDuplex(bool validSignal) DEBUG1("State to RELAYING_WAIT_RF"); m_state = FS_RELAYING_WAIT_RF; + serial.writeFMStatus(m_state); + m_ackDelayTimer.start(); if (m_extEnabled) @@ -744,6 +754,7 @@ void CFM::relayingRFStateSimplex(bool validSignal) if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) { DEBUG1("State to TIMEOUT_RF"); m_state = FS_TIMEOUT_RF; + serial.writeFMStatus(m_state); m_timeoutTimer.stop(); @@ -756,6 +767,8 @@ void CFM::relayingRFStateSimplex(bool validSignal) DEBUG1("State to RELAYING_WAIT_RF"); m_state = FS_RELAYING_WAIT_RF; + serial.writeFMStatus(m_state); + m_ackDelayTimer.start(); if (m_extEnabled) @@ -771,11 +784,14 @@ void CFM::relayingRFWaitStateDuplex(bool validSignal) DEBUG1("State to RELAYING_RF"); m_state = FS_RELAYING_RF; + serial.writeFMStatus(m_state); + m_ackDelayTimer.stop(); } else { if (m_ackDelayTimer.isRunning() && m_ackDelayTimer.hasExpired()) { DEBUG1("State to HANG"); m_state = FS_HANG; + serial.writeFMStatus(m_state); if (m_ackMinTimer.isRunning()) { if (m_ackMinTimer.hasExpired()) { @@ -809,11 +825,15 @@ void CFM::relayingRFWaitStateSimplex(bool validSignal) DEBUG1("State to RELAYING_RF"); m_state = FS_RELAYING_RF; + serial.writeFMStatus(m_state); + m_ackDelayTimer.stop(); } else { if (m_ackDelayTimer.isRunning() && m_ackDelayTimer.hasExpired()) { DEBUG1("State to LISTENING"); m_state = FS_LISTENING; + serial.writeFMStatus(m_state); + m_ackDelayTimer.stop(); m_timeoutTimer.stop(); } @@ -826,6 +846,8 @@ void CFM::kerchunkExtStateDuplex(bool validSignal) if (m_kerchunkTimer.hasExpired()) { DEBUG1("State to RELAYING_EXT"); m_state = FS_RELAYING_EXT; + serial.writeFMStatus(m_state); + m_kerchunkTimer.stop(); if (m_callsignAtStart && m_callsignAtLatch) { sendCallsign(); @@ -835,11 +857,12 @@ void CFM::kerchunkExtStateDuplex(bool validSignal) } else { DEBUG1("State to LISTENING"); m_state = FS_LISTENING; + serial.writeFMStatus(m_state); + m_kerchunkTimer.stop(); m_timeoutTimer.stop(); m_ackMinTimer.stop(); m_callsignTimer.stop(); - m_statusTimer.stop(); m_needReverse = true; } } @@ -850,6 +873,8 @@ void CFM::relayingExtStateDuplex(bool validSignal) if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) { DEBUG1("State to TIMEOUT_EXT"); m_state = FS_TIMEOUT_EXT; + serial.writeFMStatus(m_state); + m_ackMinTimer.stop(); m_timeoutTimer.stop(); m_timeoutTone.start(); @@ -857,6 +882,7 @@ void CFM::relayingExtStateDuplex(bool validSignal) } else { DEBUG1("State to RELAYING_WAIT_EXT"); m_state = FS_RELAYING_WAIT_EXT; + serial.writeFMStatus(m_state); m_ackDelayTimer.start(); } @@ -872,12 +898,14 @@ void CFM::relayingExtStateSimplex(bool validSignal) if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) { DEBUG1("State to TIMEOUT_EXT"); m_state = FS_TIMEOUT_EXT; + serial.writeFMStatus(m_state); m_timeoutTimer.stop(); } } else { DEBUG1("State to RELAYING_WAIT_EXT"); m_state = FS_RELAYING_WAIT_EXT; + serial.writeFMStatus(m_state); m_ackDelayTimer.start(); } } @@ -887,11 +915,13 @@ void CFM::relayingExtWaitStateDuplex(bool validSignal) if (validSignal) { DEBUG1("State to RELAYING_EXT"); m_state = FS_RELAYING_EXT; + serial.writeFMStatus(m_state); m_ackDelayTimer.stop(); } else { if (m_ackDelayTimer.isRunning() && m_ackDelayTimer.hasExpired()) { DEBUG1("State to HANG"); m_state = FS_HANG; + serial.writeFMStatus(m_state); if (m_ackMinTimer.isRunning()) { if (m_ackMinTimer.hasExpired()) { @@ -922,11 +952,14 @@ void CFM::relayingExtWaitStateSimplex(bool validSignal) if (validSignal) { DEBUG1("State to RELAYING_EXT"); m_state = FS_RELAYING_EXT; + serial.writeFMStatus(m_state); m_ackDelayTimer.stop(); } else { if (m_ackDelayTimer.isRunning() && m_ackDelayTimer.hasExpired()) { DEBUG1("State to LISTENING"); m_state = FS_LISTENING; + serial.writeFMStatus(m_state); + m_ackDelayTimer.stop(); m_timeoutTimer.stop(); m_needReverse = true; @@ -942,6 +975,8 @@ void CFM::hangStateDuplex(bool validRFSignal, bool validExtSignal) DEBUG1("State to RELAYING_RF"); m_state = FS_RELAYING_RF; + serial.writeFMStatus(m_state); + DEBUG1("Stop ack"); m_rfAck.stop(); m_extAck.stop(); @@ -949,6 +984,8 @@ void CFM::hangStateDuplex(bool validRFSignal, bool validExtSignal) } else if (validExtSignal) { DEBUG1("State to RELAYING_EXT"); m_state = FS_RELAYING_EXT; + serial.writeFMStatus(m_state); + DEBUG1("Stop ack"); m_rfAck.stop(); m_extAck.stop(); @@ -957,8 +994,9 @@ void CFM::hangStateDuplex(bool validRFSignal, bool validExtSignal) if (m_hangTimer.isRunning() && m_hangTimer.hasExpired()) { DEBUG1("State to LISTENING"); m_state = FS_LISTENING; + serial.writeFMStatus(m_state); + m_hangTimer.stop(); - m_statusTimer.stop(); if (m_callsignAtEnd) sendCallsign(); @@ -982,6 +1020,7 @@ void CFM::timeoutRFStateDuplex(bool validSignal) DEBUG1("State to TIMEOUT_WAIT_RF"); m_state = FS_TIMEOUT_WAIT_RF; + serial.writeFMStatus(m_state); if (m_callsignAtEnd) sendCallsign(); @@ -1003,6 +1042,7 @@ void CFM::timeoutRFStateSimplex(bool validSignal) DEBUG1("State to TIMEOUT_WAIT_RF"); m_state = FS_TIMEOUT_WAIT_RF; + serial.writeFMStatus(m_state); m_ackDelayTimer.start(); } @@ -1016,11 +1056,14 @@ void CFM::timeoutRFWaitStateDuplex(bool validSignal) DEBUG1("State to TIMEOUT_RF"); m_state = FS_TIMEOUT_RF; + serial.writeFMStatus(m_state); m_ackDelayTimer.stop(); } else { if (m_ackDelayTimer.isRunning() && m_ackDelayTimer.hasExpired()) { DEBUG1("State to HANG"); m_state = FS_HANG; + serial.writeFMStatus(m_state); + m_timeoutTone.stop(); DEBUG1("Send RF ack"); m_rfAck.start(); @@ -1045,11 +1088,14 @@ void CFM::timeoutRFWaitStateSimplex(bool validSignal) DEBUG1("State to TIMEOUT_RF"); m_state = FS_TIMEOUT_RF; + serial.writeFMStatus(m_state); m_ackDelayTimer.stop(); } else { if (m_ackDelayTimer.isRunning() && m_ackDelayTimer.hasExpired()) { DEBUG1("State to LISTENING"); m_state = FS_LISTENING; + serial.writeFMStatus(m_state); + m_ackDelayTimer.stop(); m_timeoutTimer.stop(); } @@ -1061,6 +1107,7 @@ void CFM::timeoutExtStateDuplex(bool validSignal) if (!validSignal) { DEBUG1("State to TIMEOUT_WAIT_EXT"); m_state = FS_TIMEOUT_WAIT_EXT; + serial.writeFMStatus(m_state); m_ackDelayTimer.start(); } @@ -1075,6 +1122,7 @@ void CFM::timeoutExtStateSimplex(bool validSignal) if (!validSignal) { DEBUG1("State to TIMEOUT_WAIT_EXT"); m_state = FS_TIMEOUT_WAIT_EXT; + serial.writeFMStatus(m_state); m_ackDelayTimer.start(); } } @@ -1084,11 +1132,14 @@ void CFM::timeoutExtWaitStateDuplex(bool validSignal) if (validSignal) { DEBUG1("State to TIMEOUT_EXT"); m_state = FS_TIMEOUT_EXT; + serial.writeFMStatus(m_state); m_ackDelayTimer.stop(); } else { if (m_ackDelayTimer.isRunning() && m_ackDelayTimer.hasExpired()) { DEBUG1("State to HANG"); m_state = FS_HANG; + serial.writeFMStatus(m_state); + m_timeoutTone.stop(); DEBUG1("Send Ext ack"); m_extAck.start(); @@ -1110,11 +1161,14 @@ void CFM::timeoutExtWaitStateSimplex(bool validSignal) if (validSignal) { DEBUG1("State to TIMEOUT_EXT"); m_state = FS_TIMEOUT_EXT; + serial.writeFMStatus(m_state); m_ackDelayTimer.stop(); } else { if (m_ackDelayTimer.isRunning() && m_ackDelayTimer.hasExpired()) { DEBUG1("State to LISTENING"); m_state = FS_LISTENING; + serial.writeFMStatus(m_state); + m_ackDelayTimer.stop(); m_timeoutTimer.stop(); m_needReverse = true; @@ -1131,7 +1185,6 @@ void CFM::linkStateMachine(bool validRFSignal, bool validExtSignal) if (!m_extSignal) { DEBUG1("State to RELAYING_RF"); m_state = FS_RELAYING_RF; - m_statusTimer.start(); serial.writeFMStatus(m_state); } @@ -1142,7 +1195,6 @@ void CFM::linkStateMachine(bool validRFSignal, bool validExtSignal) if (!m_rfSignal) { DEBUG1("State to RELAYING_EXT"); m_state = FS_RELAYING_EXT; - m_statusTimer.start(); serial.writeFMStatus(m_state); } @@ -1158,7 +1210,7 @@ void CFM::linkStateMachine(bool validRFSignal, bool validExtSignal) if (!m_extSignal) { DEBUG1("State to LISTENING"); m_state = FS_LISTENING; - m_statusTimer.stop(); + serial.writeFMStatus(m_state); } m_rfSignal = false; @@ -1171,7 +1223,7 @@ void CFM::linkStateMachine(bool validRFSignal, bool validExtSignal) if (!m_rfSignal) { DEBUG1("State to LISTENING"); m_state = FS_LISTENING; - m_statusTimer.stop(); + serial.writeFMStatus(m_state); } m_needReverse = true; diff --git a/FM.h b/FM.h index d50b5cd..efb808f 100644 --- a/FM.h +++ b/FM.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020,2021 by Jonathan Naylor G4KLX + * Copyright (C) 2020,2021,2023 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -35,21 +35,6 @@ #include "FMUpSampler.h" #include "FMNoiseSquelch.h" -enum FM_STATE { - FS_LISTENING, - FS_KERCHUNK_RF, - FS_RELAYING_RF, - FS_RELAYING_WAIT_RF, - FS_TIMEOUT_RF, - FS_TIMEOUT_WAIT_RF, - FS_KERCHUNK_EXT, - FS_RELAYING_EXT, - FS_RELAYING_WAIT_EXT, - FS_TIMEOUT_EXT, - FS_TIMEOUT_WAIT_EXT, - FS_HANG -}; - class CFM { public: @@ -78,7 +63,7 @@ private: CFMCTCSSTX m_ctcssTX; CFMNoiseSquelch m_squelch; CFMTimeout m_timeoutTone; - FM_STATE m_state; + uint8_t m_state; bool m_callsignAtStart; bool m_callsignAtEnd; bool m_callsignAtLatch; @@ -89,7 +74,6 @@ private: CFMTimer m_ackMinTimer; CFMTimer m_ackDelayTimer; CFMTimer m_hangTimer; - CFMTimer m_statusTimer; CFMTimer m_reverseTimer; bool m_needReverse; CFMDirectFormI m_filterStage1; diff --git a/Version.h b/Version.h index c86e21f..58884a9 100644 --- a/Version.h +++ b/Version.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020,2021,2022 by Jonathan Naylor G4KLX + * Copyright (C) 2020,2021,2022,2023 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ #if !defined(VERSION_H) #define VERSION_H -#define VERSION "20221121" +#define VERSION "20230118" #endif