Browse Source

fix 2nd frame detection

for 2ch HM
and add faster exiting CMT wait state
pull/1394/head
rejoe2 9 months ago
committed by GitHub
parent
commit
bfedf4f0c2
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 25
      src/hm/Communication.h
  2. 48
      src/hm/Heuristic.h
  3. 3
      src/hm/HeuristicInv.h
  4. 24
      src/hm/hmRadio.h
  5. 5
      src/hm/radio.h
  6. 5
      src/hms/hmsRadio.h

25
src/hm/Communication.h

@ -86,7 +86,7 @@ class Communication : public CommQueue<> {
mIsRetransmit = false; mIsRetransmit = false;
if(NULL == q->iv->radio) if(NULL == q->iv->radio)
cmdDone(false); // can't communicate while radio is not defined! 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->mCmd = q->cmd;
q->iv->mIsSingleframeReq = false; q->iv->mIsSingleframeReq = false;
mFramesExpected = getFramesExpected(q); // function to get expected frame count. mFramesExpected = getFramesExpected(q); // function to get expected frame count.
@ -134,20 +134,23 @@ class Communication : public CommQueue<> {
DPRINT_IVID(DBG_INFO, q->iv->id); DPRINT_IVID(DBG_INFO, q->iv->id);
DBGPRINT(F("request timeout: ")); DBGPRINT(F("request timeout: "));
DBGPRINT(String(q->iv->radio->mRadioWaitTime.getRunTime())); DBGPRINT(String(q->iv->radio->mRadioWaitTime.getRunTime()));
DBGPRINT(F("ms")); DBGPRINTLN(F("ms"));
if(INV_RADIO_TYPE_NRF == q->iv->ivRadioType) { /*if(INV_RADIO_TYPE_NRF == q->iv->ivRadioType) {
DBGPRINT(F(", retries "));
DBGPRINTLN(String(q->iv->radio->mTxRetriesNext));
DBGPRINT(F(", ARC ")); DBGPRINT(F(", ARC "));
DBGPRINT(String(q->iv->radio->getARC())); DBGPRINT(String(q->iv->radio->getARC()));
DBGPRINT(F(", PLOS ")); DBGPRINT(F(", PLOS "));
DBGPRINTLN(String(q->iv->radio->getPLOS())); DBGPRINTLN(String(q->iv->radio->getPLOS()));
} else } else
DBGPRINTLN(""); DBGPRINTLN("");*/
} }
if(!q->iv->mGotFragment) { if(!q->iv->mGotFragment) {
if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) { 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)); q->iv->radio->switchFrequency(q->iv, HOY_BOOT_FREQ_KHZ, (q->iv->config->frequency*FREQ_STEP_KHZ + HOY_BASE_FREQ_KHZ));
mWaitTime.startTimeMonitor(1000); mWaitTime.startTimeMonitor(1000);
} else { } else {
mHeu.setIvRetriesBad(q->iv);
if(IV_MI == q->iv->ivGen) if(IV_MI == q->iv->ivGen)
q->iv->mIvTxCnt++; q->iv->mIvTxCnt++;
@ -180,8 +183,11 @@ class Communication : public CommQueue<> {
q->iv->mDtuRxCnt++; q->iv->mDtuRxCnt++;
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
if(parseFrame(p)) if(parseFrame(p)) {
q->iv->curFrmCnt++; 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 } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command
if(parseDevCtrl(p, q)) if(parseDevCtrl(p, q))
closeRequest(q, true); closeRequest(q, true);
@ -291,10 +297,10 @@ class Communication : public CommQueue<> {
DBGPRINT(String(p->millis)); DBGPRINT(String(p->millis));
DBGPRINT(F("ms | ")); DBGPRINT(F("ms | "));
DBGPRINT(String(p->len)); DBGPRINT(String(p->len));
DBGPRINT(F(", ARC ")); /*DBGPRINT(F(", ARC "));
DBGPRINT(String(p->arc)); DBGPRINT(String(p->arc));
DBGPRINT(F(", PLOS ")); DBGPRINT(F(", PLOS "));
DBGPRINT(String(p->plos)); DBGPRINT(String(p->plos));*/
DBGPRINT(F(" |")); DBGPRINT(F(" |"));
if(INV_RADIO_TYPE_NRF == q->iv->ivRadioType) { if(INV_RADIO_TYPE_NRF == q->iv->ivRadioType) {
DBGPRINT(F(" CH")); DBGPRINT(F(" CH"));
@ -417,6 +423,8 @@ class Communication : public CommQueue<> {
} }
inline bool parseMiFrame(packet_t *p, const queue_s *q) { 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) if ((p->packet[0] == MI_REQ_CH1 + ALL_FRAMES)
|| (p->packet[0] == MI_REQ_CH2 + ALL_FRAMES) || (p->packet[0] == MI_REQ_CH2 + ALL_FRAMES)
|| ((p->packet[0] >= (MI_REQ_4CH + 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 record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the record structure
rec->ts = q->ts; 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]); 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; return true;
@ -527,7 +534,7 @@ class Communication : public CommQueue<> {
len -= 2; len -= 2;
DPRINT_IVID(DBG_INFO, q->iv->id); //DPRINT_IVID(DBG_INFO, q->iv->id);
DBGPRINT(F("Payload (")); DBGPRINT(F("Payload ("));
DBGPRINT(String(len)); DBGPRINT(String(len));
if(*mPrintWholeTrace) { if(*mPrintWholeTrace) {

48
src/hm/Heuristic.h

@ -23,8 +23,8 @@
class Heuristic { class Heuristic {
public: public:
uint8_t getTxCh(Inverter<> *iv) { uint8_t getTxCh(Inverter<> *iv) {
if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) if(iv->ivRadioType != INV_RADIO_TYPE_NRF)
return 0; // not used for these inverter types return 0; // not used for other than nRF inverter types
HeuristicInv *ih = &iv->heuristics; HeuristicInv *ih = &iv->heuristics;
@ -66,6 +66,8 @@ class Heuristic {
ih->testPeriodFailCnt = 0; ih->testPeriodFailCnt = 0;
} }
iv->radio->mTxRetriesNext = getIvRetries(iv);
return id2Ch(ih->txRfChId); return id2Ch(ih->txRfChId);
} }
@ -155,6 +157,48 @@ class Heuristic {
DBGPRINTLN(String(iv->config->powerLevel)); 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: private:
bool isNewTxCh(HeuristicInv *ih) { bool isNewTxCh(HeuristicInv *ih) {
return ih->txRfChId != ih->lastBestTxChId; return ih->txRfChId != ih->lastBestTxChId;

3
src/hm/HeuristicInv.h

@ -27,6 +27,9 @@ class HeuristicInv {
uint8_t testChId = 0; uint8_t testChId = 0;
int8_t saveOldTestQuality = -6; int8_t saveOldTestQuality = -6;
uint8_t lastRxFragments = 0; 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__*/ #endif /*__HEURISTIC_INV_H__*/

24
src/hm/hmRadio.h

@ -161,7 +161,7 @@ class HmRadio : public Radio {
rxPendular = false; rxPendular = false;
mNRFloopChannels = (mLastIv->ivGen == IV_MI); mNRFloopChannels = (mLastIv->ivGen == IV_MI);
innerLoopTimeout = DURATION_TXFRAME; innerLoopTimeout = mLastIv->ivGen != IV_MI ? DURATION_TXFRAME : DURATION_ONEFRAME;
} }
if(rx_ready) { if(rx_ready) {
@ -293,13 +293,13 @@ class HmRadio : public Radio {
return mNrf24->isPVariant(); return mNrf24->isPVariant();
} }
uint8_t getARC(void) { /*uint8_t getARC(void) {
return mNrf24->getARC(); return mNrf24->getARC();
} }
uint8_t getPLOS(void) { uint8_t getPLOS(void) {
return mNrf24->getPLOS(); return mNrf24->getPLOS();
} }*/
private: private:
inline bool getReceived(void) { 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.len = (len > MAX_RF_PAYLOAD_SIZE) ? MAX_RF_PAYLOAD_SIZE : len;
p.rssi = mNrf24->testRPD() ? -64 : -75; p.rssi = mNrf24->testRPD() ? -64 : -75;
p.millis = millis() - mMillis; p.millis = millis() - mMillis;
p.arc = mNrf24->getARC(); //p.arc = mNrf24->getARC();
p.plos = mNrf24->getPLOS(); //p.plos = mNrf24->getPLOS();
mNrf24->read(p.packet, p.len); mNrf24->read(p.packet, p.len);
if (p.packet[0] != 0x00) { if (p.packet[0] != 0x00) {
@ -356,18 +356,23 @@ class HmRadio : public Radio {
mTxChIdx = iv->heuristics.txRfChId; mTxChIdx = iv->heuristics.txRfChId;
if(*mSerialDebug) { 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) { if(!isRetransmit) {
DPRINT(DBG_INFO, "last tx setup: "); DPRINT(DBG_INFO, "last tx setup: ");
DBGPRINT(String(mTxSetupTime)); DBGPRINT(String(mTxSetupTime));
DBGPRINTLN("ms"); DBGPRINTLN("ms");
} }*/
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("TX ")); DBGPRINT(F("TX "));
DBGPRINT(String(len)); DBGPRINT(String(len));
DBGPRINT(" CH"); DBGPRINT(" CH");
DBGPRINT(String(mRfChLst[mTxChIdx])); DBGPRINT(String(mRfChLst[mTxChIdx]));
DBGPRINT(F(" | ")); DBGPRINT(F(", "));
DBGPRINT(String(mTxRetriesNext));
DBGPRINT(F(" retries | "));
if(*mPrintWholeTrace) { if(*mPrintWholeTrace) {
if(*mPrivacyMode) if(*mPrivacyMode)
ah::dumpBuf(mTxBuf, len, 1, 4); ah::dumpBuf(mTxBuf, len, 1, 4);
@ -383,6 +388,10 @@ class HmRadio : public Radio {
} }
mNrf24->stopListening(); mNrf24->stopListening();
if(!isRetransmit && mTxRetries != mTxRetriesNext) {
mNrf24->setRetries(3, mTxRetriesNext);
mTxRetries = mTxRetriesNext;
}
mNrf24->setChannel(mRfChLst[mTxChIdx]); mNrf24->setChannel(mRfChLst[mTxChIdx]);
mNrf24->openWritingPipe(reinterpret_cast<uint8_t*>(&iv->radioId.u64)); mNrf24->openWritingPipe(reinterpret_cast<uint8_t*>(&iv->radioId.u64));
mNrf24->startWrite(mTxBuf, len, false); // false = request ACK response mNrf24->startWrite(mTxBuf, len, false); // false = request ACK response
@ -425,6 +434,7 @@ class HmRadio : public Radio {
bool rxPendular = false; bool rxPendular = false;
uint32_t innerLoopTimeout = DURATION_LISTEN_MIN; uint32_t innerLoopTimeout = DURATION_LISTEN_MIN;
uint8_t mTxSetupTime = 0; uint8_t mTxSetupTime = 0;
uint8_t mTxRetries = 15; // memorize last setting for mNrf24->setRetries(3, 15);
std::unique_ptr<SPIClass> mSpi; std::unique_ptr<SPIClass> mSpi;
std::unique_ptr<RF24> mNrf24; std::unique_ptr<RF24> mNrf24;

5
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 switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) { return true; }
virtual bool isChipConnected(void) { return false; } virtual bool isChipConnected(void) { return false; }
virtual bool loop(void) = 0; virtual bool loop(void) = 0;
virtual uint8_t getARC(void) { return 0xff; } //virtual uint8_t getARC(void) { return 0xff; }
virtual uint8_t getPLOS(void) { return 0xff; } //virtual uint8_t getPLOS(void) { return 0xff; }
void handleIntr(void) { void handleIntr(void) {
mIrqRcvd = true; mIrqRcvd = true;
@ -78,6 +78,7 @@ class Radio {
std::queue<packet_t> mBufCtrl; std::queue<packet_t> mBufCtrl;
uint8_t mIrqOk = IRQ_UNKNOWN; uint8_t mIrqOk = IRQ_UNKNOWN;
TimeMonitor mRadioWaitTime = TimeMonitor(0, true); // start as expired (due to code in RESET state) 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: protected:
virtual void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) = 0; virtual void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) = 0;

5
src/hms/hmsRadio.h

@ -166,9 +166,10 @@ class CmtRadio : public Radio {
mBufCtrl.push(p); mBufCtrl.push(p);
// this code completly stops communication! // 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... // 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; CmtType mCmt;

Loading…
Cancel
Save