From bfedf4f0c23db7161ae3aadd4995f88b5f9c815d Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Tue, 23 Jan 2024 16:09:54 +0100 Subject: [PATCH] fix 2nd frame detection for 2ch HM and add faster exiting CMT wait state --- src/hm/Communication.h | 25 ++++++++++++++-------- src/hm/Heuristic.h | 48 ++++++++++++++++++++++++++++++++++++++++-- src/hm/HeuristicInv.h | 3 +++ src/hm/hmRadio.h | 24 +++++++++++++++------ src/hm/radio.h | 5 +++-- src/hms/hmsRadio.h | 5 +++-- 6 files changed, 88 insertions(+), 22 deletions(-) diff --git a/src/hm/Communication.h b/src/hm/Communication.h index 98dd06e1..15ca3d5d 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -86,7 +86,7 @@ class Communication : public CommQueue<> { mIsRetransmit = false; if(NULL == q->iv->radio) cmdDone(false); // can't communicate while radio is not defined! - mFirstTry = q->iv->isAvailable(); + mFirstTry = INV_RADIO_TYPE_NRF == q->iv->ivRadioType && q->iv->isAvailable(); q->iv->mCmd = q->cmd; q->iv->mIsSingleframeReq = false; mFramesExpected = getFramesExpected(q); // function to get expected frame count. @@ -134,20 +134,23 @@ class Communication : public CommQueue<> { DPRINT_IVID(DBG_INFO, q->iv->id); DBGPRINT(F("request timeout: ")); DBGPRINT(String(q->iv->radio->mRadioWaitTime.getRunTime())); - DBGPRINT(F("ms")); - if(INV_RADIO_TYPE_NRF == q->iv->ivRadioType) { + DBGPRINTLN(F("ms")); + /*if(INV_RADIO_TYPE_NRF == q->iv->ivRadioType) { + DBGPRINT(F(", retries ")); + DBGPRINTLN(String(q->iv->radio->mTxRetriesNext)); DBGPRINT(F(", ARC ")); DBGPRINT(String(q->iv->radio->getARC())); DBGPRINT(F(", PLOS ")); DBGPRINTLN(String(q->iv->radio->getPLOS())); } else - DBGPRINTLN(""); + DBGPRINTLN("");*/ } if(!q->iv->mGotFragment) { if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) { q->iv->radio->switchFrequency(q->iv, HOY_BOOT_FREQ_KHZ, (q->iv->config->frequency*FREQ_STEP_KHZ + HOY_BASE_FREQ_KHZ)); mWaitTime.startTimeMonitor(1000); } else { + mHeu.setIvRetriesBad(q->iv); if(IV_MI == q->iv->ivGen) q->iv->mIvTxCnt++; @@ -180,8 +183,11 @@ class Communication : public CommQueue<> { q->iv->mDtuRxCnt++; if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command - if(parseFrame(p)) + if(parseFrame(p)) { q->iv->curFrmCnt++; + if(!mIsRetransmit && (p->packet[9] == 0x02 || p->packet[9] == 0x82) && p->millis < 85) + mHeu.setIvRetriesGood(q->iv,p->millis < 70); + } } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command if(parseDevCtrl(p, q)) closeRequest(q, true); @@ -291,10 +297,10 @@ class Communication : public CommQueue<> { DBGPRINT(String(p->millis)); DBGPRINT(F("ms | ")); DBGPRINT(String(p->len)); - DBGPRINT(F(", ARC ")); + /*DBGPRINT(F(", ARC ")); DBGPRINT(String(p->arc)); DBGPRINT(F(", PLOS ")); - DBGPRINT(String(p->plos)); + DBGPRINT(String(p->plos));*/ DBGPRINT(F(" |")); if(INV_RADIO_TYPE_NRF == q->iv->ivRadioType) { DBGPRINT(F(" CH")); @@ -417,6 +423,8 @@ class Communication : public CommQueue<> { } inline bool parseMiFrame(packet_t *p, const queue_s *q) { + if(!mIsRetransmit && p->packet[9] == 0x00 && p->millis < 35) //first frame is fast? + mHeu.setIvRetriesGood(q->iv,p->millis < 22); if ((p->packet[0] == MI_REQ_CH1 + ALL_FRAMES) || (p->packet[0] == MI_REQ_CH2 + ALL_FRAMES) || ((p->packet[0] >= (MI_REQ_4CH + ALL_FRAMES)) @@ -436,7 +444,6 @@ class Communication : public CommQueue<> { record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the record structure rec->ts = q->ts; miStsConsolidate(q, ((p->packet[0] == 0x88) ? 1 : 2), rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]); - //mHeu.setGotFragment(q->iv); only do this when we are through the cycle? } return true; @@ -527,7 +534,7 @@ class Communication : public CommQueue<> { len -= 2; - DPRINT_IVID(DBG_INFO, q->iv->id); + //DPRINT_IVID(DBG_INFO, q->iv->id); DBGPRINT(F("Payload (")); DBGPRINT(String(len)); if(*mPrintWholeTrace) { diff --git a/src/hm/Heuristic.h b/src/hm/Heuristic.h index 64c78cc8..642eca13 100644 --- a/src/hm/Heuristic.h +++ b/src/hm/Heuristic.h @@ -23,8 +23,8 @@ class Heuristic { public: uint8_t getTxCh(Inverter<> *iv) { - if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) - return 0; // not used for these inverter types + if(iv->ivRadioType != INV_RADIO_TYPE_NRF) + return 0; // not used for other than nRF inverter types HeuristicInv *ih = &iv->heuristics; @@ -66,6 +66,8 @@ class Heuristic { ih->testPeriodFailCnt = 0; } + iv->radio->mTxRetriesNext = getIvRetries(iv); + return id2Ch(ih->txRfChId); } @@ -155,6 +157,48 @@ class Heuristic { DBGPRINTLN(String(iv->config->powerLevel)); } + uint8_t getIvRetries(Inverter<> *iv) { + if(iv->heuristics.rxSpeeds[0]) + return 5; + if(iv->heuristics.rxSpeeds[1]) + return 10; + return 15; + } + + void setIvRetriesGood(Inverter<> *iv, bool veryGood) { + if(iv->ivRadioType != INV_RADIO_TYPE_NRF) + return; // not used for other than nRF inverter types + + if(iv->heuristics.rxSpeedCnt[veryGood] > 9) + return; + iv->heuristics.rxSpeedCnt[veryGood]++; + iv->heuristics.rxSpeeds[veryGood] = true; + } + + void setIvRetriesBad(Inverter<> *iv) { + if(iv->ivRadioType != INV_RADIO_TYPE_NRF) + return; // not used for other than nRF inverter types + + if(iv->heuristics.rxSpeedCnt[0]) { + iv->heuristics.rxSpeedCnt[0]--; + return; + } + if(iv->heuristics.rxSpeeds[0]) { + iv->heuristics.rxSpeeds[0] = false; + return; + } + + if(iv->heuristics.rxSpeedCnt[1]) { + iv->heuristics.rxSpeedCnt[1]--; + return; + } + if(iv->heuristics.rxSpeeds[1]) { + iv->heuristics.rxSpeeds[1] = false; + return; + } + return; + } + private: bool isNewTxCh(HeuristicInv *ih) { return ih->txRfChId != ih->lastBestTxChId; diff --git a/src/hm/HeuristicInv.h b/src/hm/HeuristicInv.h index e7ad6edd..fc782a7b 100644 --- a/src/hm/HeuristicInv.h +++ b/src/hm/HeuristicInv.h @@ -27,6 +27,9 @@ class HeuristicInv { uint8_t testChId = 0; int8_t saveOldTestQuality = -6; uint8_t lastRxFragments = 0; + bool rxSpeeds[2] = {false,false}; // is inverter responding very fast respective fast? + uint8_t rxSpeedCnt[2] = {0,0}; // count how many messages had been received very fast respective fast (10 max) + }; #endif /*__HEURISTIC_INV_H__*/ diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index ef37e266..9915a9a8 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -161,7 +161,7 @@ class HmRadio : public Radio { rxPendular = false; mNRFloopChannels = (mLastIv->ivGen == IV_MI); - innerLoopTimeout = DURATION_TXFRAME; + innerLoopTimeout = mLastIv->ivGen != IV_MI ? DURATION_TXFRAME : DURATION_ONEFRAME; } if(rx_ready) { @@ -293,13 +293,13 @@ class HmRadio : public Radio { return mNrf24->isPVariant(); } - uint8_t getARC(void) { + /*uint8_t getARC(void) { return mNrf24->getARC(); } uint8_t getPLOS(void) { return mNrf24->getPLOS(); - } + }*/ private: inline bool getReceived(void) { @@ -315,8 +315,8 @@ class HmRadio : public Radio { p.len = (len > MAX_RF_PAYLOAD_SIZE) ? MAX_RF_PAYLOAD_SIZE : len; p.rssi = mNrf24->testRPD() ? -64 : -75; p.millis = millis() - mMillis; - p.arc = mNrf24->getARC(); - p.plos = mNrf24->getPLOS(); + //p.arc = mNrf24->getARC(); + //p.plos = mNrf24->getPLOS(); mNrf24->read(p.packet, p.len); if (p.packet[0] != 0x00) { @@ -356,18 +356,23 @@ class HmRadio : public Radio { mTxChIdx = iv->heuristics.txRfChId; if(*mSerialDebug) { + /* remark rejoe2: imo this has no added value here. + As this belongs to the last tx cycle, we should print that info + directly when switching from tx to rx. Otherwise we might confuse users. if(!isRetransmit) { DPRINT(DBG_INFO, "last tx setup: "); DBGPRINT(String(mTxSetupTime)); DBGPRINTLN("ms"); - } + }*/ DPRINT_IVID(DBG_INFO, iv->id); DBGPRINT(F("TX ")); DBGPRINT(String(len)); DBGPRINT(" CH"); DBGPRINT(String(mRfChLst[mTxChIdx])); - DBGPRINT(F(" | ")); + DBGPRINT(F(", ")); + DBGPRINT(String(mTxRetriesNext)); + DBGPRINT(F(" retries | ")); if(*mPrintWholeTrace) { if(*mPrivacyMode) ah::dumpBuf(mTxBuf, len, 1, 4); @@ -383,6 +388,10 @@ class HmRadio : public Radio { } mNrf24->stopListening(); + if(!isRetransmit && mTxRetries != mTxRetriesNext) { + mNrf24->setRetries(3, mTxRetriesNext); + mTxRetries = mTxRetriesNext; + } mNrf24->setChannel(mRfChLst[mTxChIdx]); mNrf24->openWritingPipe(reinterpret_cast(&iv->radioId.u64)); mNrf24->startWrite(mTxBuf, len, false); // false = request ACK response @@ -425,6 +434,7 @@ class HmRadio : public Radio { bool rxPendular = false; uint32_t innerLoopTimeout = DURATION_LISTEN_MIN; uint8_t mTxSetupTime = 0; + uint8_t mTxRetries = 15; // memorize last setting for mNrf24->setRetries(3, 15); std::unique_ptr mSpi; std::unique_ptr mNrf24; diff --git a/src/hm/radio.h b/src/hm/radio.h index a71e24c7..e6baf792 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -29,8 +29,8 @@ class Radio { virtual bool switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) { return true; } virtual bool isChipConnected(void) { return false; } virtual bool loop(void) = 0; - virtual uint8_t getARC(void) { return 0xff; } - virtual uint8_t getPLOS(void) { return 0xff; } + //virtual uint8_t getARC(void) { return 0xff; } + //virtual uint8_t getPLOS(void) { return 0xff; } void handleIntr(void) { mIrqRcvd = true; @@ -78,6 +78,7 @@ class Radio { std::queue mBufCtrl; uint8_t mIrqOk = IRQ_UNKNOWN; TimeMonitor mRadioWaitTime = TimeMonitor(0, true); // start as expired (due to code in RESET state) + uint8_t mTxRetriesNext = 15; // let heuristics tell us the next reties count (for nRF type radios only) protected: virtual void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) = 0; diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index 48ff3750..3c569e02 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -166,9 +166,10 @@ class CmtRadio : public Radio { mBufCtrl.push(p); // this code completly stops communication! - //if(p.packet[9] > ALL_FRAMES) // indicates last frame + if(p.packet[9] > ALL_FRAMES) // indicates last frame // mRadioWaitTime.stopTimeMonitor(); // we got everything we expected and can exit rx mode... - //optionally instead: mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first get back to rx mode? + //optionally instead: + mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first get back to rx mode? } CmtType mCmt;