diff --git a/Firmware/LoRaSerial/Commands.ino b/Firmware/LoRaSerial/Commands.ino index 7a37dcc0..a2faa946 100644 --- a/Firmware/LoRaSerial/Commands.ino +++ b/Firmware/LoRaSerial/Commands.ino @@ -589,7 +589,7 @@ bool commandAT(const char * commandString) if (irqFlags & 1) systemPrintln(" CAD Detected"); systemPrint(" receiveInProcess: "); - systemPrintln(receiveInProcess() ? "True" : "False"); + systemPrintln(receiveInProcess(false) ? "True" : "False"); outputSerialData(true); petWDT(); diff --git a/Firmware/LoRaSerial/Radio.ino b/Firmware/LoRaSerial/Radio.ino index 3c90a88c..84e8f5a1 100644 --- a/Firmware/LoRaSerial/Radio.ino +++ b/Firmware/LoRaSerial/Radio.ino @@ -249,7 +249,7 @@ void returnToReceiving() { radioCallHistory[RADIO_CALL_returnToReceiving] = millis(); - if (receiveInProcess() == true) return; //Do not touch the radio if it is already receiving + if (receiveInProcess(false) == true) return; //Do not touch the radio if it is already receiving int state; if (settings.radioSpreadFactor > 6) @@ -617,32 +617,25 @@ unsigned long mSecToChannelZero() } //Returns true if the radio indicates we have an ongoing reception -bool receiveInProcess() +bool receiveInProcess(bool startClock) { uint8_t radioStatus = radio.getModemStatus(); radioStatus &= 0b11011; //Get bits 0, 1, 3, and 4 //Known states where a reception is in progress - if (radioStatus == 0b00001) - return (true); - else if (radioStatus == 0b00011) - return (true); - else if (radioStatus == 0b01011) - return (true); - - // switch (radioStatus) - // { - // default: - // Serial.print("Unknown status: 0b"); - // Serial.println(radioStatus, BIN); - // break; - // case (0b00000): - // //No receive in process - // case (0b10000): - // //Modem clear. No receive in process - // break; - // } - + switch (radioStatus) + { + case 0b00001: + case 0b00011: + case 0b01011: + if (startClock && (!channelTimerMsec)) + { + //Compute the approximate time for the next hop + startChannelTimer(settings.maxDwellTime - ((settings.txToRxUsec * 25) / 4000)); + triggerEvent(TRIGGER_RECEIVE_IN_PROCESS); + } + return (true); + } return (false); } @@ -3050,7 +3043,7 @@ bool retransmitDatagram(VIRTUAL_CIRCUIT * vc) //Drop this datagram if the receiver is active if ( - (receiveInProcess() == true) + (receiveInProcess(false) == true) || (transactionComplete == true) || ( //If we are in VC mode, and destination is not broadcast, @@ -3071,7 +3064,7 @@ bool retransmitDatagram(VIRTUAL_CIRCUIT * vc) systemPrint("TX failed: "); if (transactionComplete) systemPrintln("RXTC"); - else if (receiveInProcess()) + else if (receiveInProcess(false)) systemPrintln("RXIP"); else systemPrintln("VC link down"); @@ -3086,7 +3079,7 @@ bool retransmitDatagram(VIRTUAL_CIRCUIT * vc) if (state == RADIOLIB_ERR_NONE) { - if (receiveInProcess() == true) + if (receiveInProcess(false) == true) { //Edge case: if we have started TX, but during the SPI transaction a preamble was detected //then return false. This will cause the radio to transmit, then a transactionComplete ISR will trigger. diff --git a/Firmware/LoRaSerial/Serial.ino b/Firmware/LoRaSerial/Serial.ino index d5e9a091..9bc7e62f 100644 --- a/Firmware/LoRaSerial/Serial.ino +++ b/Firmware/LoRaSerial/Serial.ino @@ -606,7 +606,7 @@ bool vcSerialMessageReceived() do { //Determine if the radio is idle - if (receiveInProcess()) + if (receiveInProcess(false)) //The radio is busy, wait until it is idle break; diff --git a/Firmware/LoRaSerial/States.ino b/Firmware/LoRaSerial/States.ino index afdd09ef..97dd8127 100644 --- a/Firmware/LoRaSerial/States.ino +++ b/Firmware/LoRaSerial/States.ino @@ -330,7 +330,7 @@ void updateRadioState() } //Is it time to send the FIND_PARTNER to the remote system - else if ((receiveInProcess() == false) && ((millis() - heartbeatTimer) >= randomTime)) + else if ((receiveInProcess(false) == false) && ((millis() - heartbeatTimer) >= randomTime)) { //Transmit the FIND_PARTNER triggerEvent(TRIGGER_TX_FIND_PARTNER); @@ -814,7 +814,7 @@ void updateRadioState() } } - else if (receiveInProcess() == false) + else if (receiveInProcess(false) == false) { //---------- //Priority 1: Transmit a HEARTBEAT if necessary @@ -995,7 +995,7 @@ void updateRadioState() //---------- //Always check for link timeout //---------- - if ((millis() - linkDownTimer) >= (LINK_BREAK_MULTIPLIER * settings.heartbeatTimeout)) + if ((millis() - linkDownTimer) >= (LINK_BREAK_MULTIPLIER * (uint32_t)settings.heartbeatTimeout)) //Break the link breakLink(); break; @@ -1182,7 +1182,7 @@ void updateRadioState() } //Nothing received - else if (receiveInProcess() == false) + else if (receiveInProcess(false) == false) { //Check for a receive timeout timeoutMsec = settings.overheadTime + ((frameAirTimeUsec + txDataAckUsec + settings.txToRxUsec) / 1000); @@ -1242,9 +1242,20 @@ void updateRadioState() //Wait for the Server to transmit a HB on Channel 0 //==================== case RADIO_DISCOVER_STANDBY: + //Hop channels when required + if (timeToHop == true) + hopChannel(); + if (channelNumber && (!channelTimerMsec)) + { + //Return to channel zero + channelNumber = 0; + setRadioFrequency(false); + } + rssi = -200; //Force RSSI LEDs off until link is up //Process the receive packet + receiveInProcess(true); if (transactionComplete == true) { triggerEvent(TRIGGER_MP_PACKET_RECEIVED); @@ -1256,6 +1267,7 @@ void updateRadioState() switch (packetType) { default: + stopChannelTimer(); triggerEvent(TRIGGER_UNKNOWN_PACKET); if (settings.debugDatagrams) { @@ -1268,14 +1280,17 @@ void updateRadioState() break; case DATAGRAM_BAD: + stopChannelTimer(); triggerEvent(TRIGGER_BAD_PACKET); break; case DATAGRAM_CRC_ERROR: + stopChannelTimer(); triggerEvent(TRIGGER_CRC_ERROR); break; case DATAGRAM_NETID_MISMATCH: + stopChannelTimer(); triggerEvent(TRIGGER_NETID_MISMATCH); break; @@ -1286,10 +1301,12 @@ void updateRadioState() case DATAGRAM_REMOTE_COMMAND: case DATAGRAM_REMOTE_COMMAND_RESPONSE: //We should not be receiving these datagrams, but if we do, just ignore + stopChannelTimer(); triggerEvent(TRIGGER_BAD_PACKET); break; case DATAGRAM_FIND_PARTNER: + stopChannelTimer(); triggerEvent(TRIGGER_RX_FIND_PARTNER); break; @@ -1302,7 +1319,6 @@ void updateRadioState() setRadioFrequency(false); //Start and adjust freq hop ISR based on remote's remaining clock - startChannelTimer(); channelTimerStart -= settings.maxDwellTime; syncChannelTimer(txSyncClocksUsec, 1); @@ -1334,6 +1350,7 @@ void updateRadioState() case DATAGRAM_DATA: //Don't deal with data until we are sync'd with server + stopChannelTimer(); triggerEvent(TRIGGER_RX_DATA); break; } @@ -1411,10 +1428,6 @@ void updateRadioState() changeState(RADIO_MP_WAIT_TX_DONE); } } - else - { - changeState(RADIO_MP_STANDBY); - } break; case DATAGRAM_HEARTBEAT: @@ -1432,7 +1445,6 @@ void updateRadioState() lastPacketReceived = millis(); //Update timestamp for Link LED blinkHeartbeatLed(true); - changeState(RADIO_MP_STANDBY); } break; @@ -1446,14 +1458,12 @@ void updateRadioState() frequencyCorrection += radio.getFrequencyError() / 1000000.0; lastPacketReceived = millis(); //Update timestamp for Link LED - - changeState(RADIO_MP_STANDBY); break; } } //If the radio is available, send any data in the serial buffer over the radio - else if (receiveInProcess() == false) + else if (receiveInProcess(false) == false) { heartbeatTimeout = ((millis() - heartbeatTimer) > heartbeatRandomTime); @@ -1482,7 +1492,7 @@ void updateRadioState() //If the client hasn't received a packet in too long, return to scanning else if (settings.server == false) { - if ((millis() - lastPacketReceived) > (settings.heartbeatTimeout * 3)) + if ((millis() - lastPacketReceived) > ((uint32_t)settings.heartbeatTimeout * LINK_BREAK_MULTIPLIER)) { if (settings.debugSync) { @@ -1623,7 +1633,7 @@ void updateRadioState() } //Determine if a receive is in process - else if (receiveInProcess()) + else if (receiveInProcess(false)) { if (!trainingPreviousRxInProgress) { @@ -1783,7 +1793,7 @@ void updateRadioState() } //Determine if a receive is in process - else if (receiveInProcess()) + else if (receiveInProcess(false)) if (!trainingPreviousRxInProgress) { trainingPreviousRxInProgress = true; @@ -1926,7 +1936,7 @@ void updateRadioState() vcReceiveHeartbeat(millis() - currentMillis); //Delay for a while before sending the HEARTBEAT - heartbeatRandomTime = random((settings.heartbeatTimeout * 2) / 10, settings.heartbeatTimeout); + heartbeatRandomTime = random(((uint32_t)settings.heartbeatTimeout * 2) / 10, settings.heartbeatTimeout); changeState(RADIO_VC_WAIT_RECEIVE); } else @@ -2193,7 +2203,7 @@ void updateRadioState() } //when not receiving process the pending transmit requests - else if (!receiveInProcess()) + else if (!receiveInProcess(false)) { //---------- //Priority 1: Transmit a HEARTBEAT if necessary @@ -2321,7 +2331,7 @@ void updateRadioState() { for (index = 0; index < MAX_VC; index++) { - if (receiveInProcess()) + if (receiveInProcess(false)) break; //Determine the first VC that is walking through connections @@ -2510,7 +2520,7 @@ void updateRadioState() //Determine if the link has timed out vc = &virtualCircuitList[index]; if ((vc->vcState != VC_STATE_LINK_DOWN) && (serverLinkBroken - || ((currentMillis - vc->lastTrafficMillis) > (LINK_BREAK_MULTIPLIER * settings.heartbeatTimeout)))) + || ((currentMillis - vc->lastTrafficMillis) > (LINK_BREAK_MULTIPLIER * (uint32_t)settings.heartbeatTimeout)))) { if (index == VC_SERVER) {