From c02c59d7a20ea99e2487a23fb4242c4bf08a1d41 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Mon, 18 Dec 2023 00:11:37 +0100 Subject: [PATCH] refacturing rx loop - second version - less impact out of nRF, less variables - tested on single HM-1500, rock solid, but timings need to be reviewed Known bug: Any limitation command will be endlessly executed, still after success... --- src/defines.h | 2 +- src/hm/Communication.h | 43 +++++++++-------- src/hm/hmInverter.h | 36 ++++++++++---- src/hm/hmRadio.h | 106 ++++++++++++++++++++--------------------- src/hm/radio.h | 1 - src/hms/cmt2300a.h | 4 +- src/hms/hmsRadio.h | 4 -- 7 files changed, 104 insertions(+), 92 deletions(-) diff --git a/src/defines.h b/src/defines.h index cf552aa0..540c20be 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 8 -#define VERSION_PATCH 2304 +#define VERSION_PATCH 2601 //------------------------------------- typedef struct { diff --git a/src/hm/Communication.h b/src/hm/Communication.h index a0c630d1..765c1dbc 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -87,7 +87,10 @@ class Communication : public CommQueue<> { cmdDone(true); // can't communicate while radio is not defined! mState = States::START; - q->iv->radio->prepareReceive(q->iv, q->cmd, false); + q->iv->mCmd = q->cmd; + q->iv->mIsSingleframeReq = false; + + //prepareReceive(q->iv, q->cmd, false); break; @@ -212,11 +215,12 @@ class Communication : public CommQueue<> { } closeRequest(q, true); if(fastNext) { + DPRINTLN(DBG_INFO, F("we should enqueue sth immediately....")); // immediately send out regular production data request // and reset mWaitTimeout - mWaitTimeout = mWaitTimeout - *mInverterGap; - chgCmd((q->iv->type == INV_TYPE_4CH) ? MI_REQ_4CH : MI_REQ_CH1); - mState = States::RESET; + //mWaitTimeout = mWaitTimeout - *mInverterGap; + //chgCmd((q->iv->type == INV_TYPE_4CH) ? MI_REQ_4CH : MI_REQ_CH1); + //mState = States::RESET; } } @@ -260,7 +264,9 @@ class Communication : public CommQueue<> { DBGPRINTLN(F(" attempts left)")); } if (!mIsRetransmit) - q->iv->radio->prepareReceive(q->iv, q->cmd, true); + q->iv->mIsSingleframeReq = true; + + //prepareReceive(q->iv, q->cmd, true); sendRetransmit(q, (framnr-1)); mIsRetransmit = true; @@ -270,23 +276,10 @@ class Communication : public CommQueue<> { compilePayload(q); - if(NULL != mCbPayload) + if((NULL != mCbPayload) && (GridOnProFilePara != q->cmd)) (mCbPayload)(q->cmd, q->iv); - bool fastNext = false; - if ((q->cmd < 11) || (q->cmd > 18)) - fastNext = true; - closeRequest(q, true); - - if(fastNext) { - // immediately send out regular production data request - // and reset mWaitTimeout - mWaitTimeout = mWaitTimeout - *mInverterGap; - chgCmd(RealTimeRunData_Debug); - mState = States::RESET; - } - break; } }); @@ -318,7 +311,9 @@ class Communication : public CommQueue<> { else ah::dumpBuf(p->packet, p->len); } else { - DBGPRINT(F("| ")); + DBGPRINT(F("| 0x")); + DHEX(p->packet[0]); + DBGPRINT(F(" ")); DBGHEXLN(p->packet[9]); } } @@ -401,7 +396,7 @@ class Communication : public CommQueue<> { accepted = false; DPRINT_IVID(DBG_INFO, q->iv->id); - DBGPRINT(F(" has ")); + DBGPRINT(F("has ")); if(!accepted) DBGPRINT(F("not ")); DBGPRINT(F("accepted power limit set point ")); DBGPRINT(String(q->iv->powerLimit[0])); @@ -469,9 +464,15 @@ class Communication : public CommQueue<> { } else DBGPRINTLN(F(")")); + if(GridOnProFilePara == q->cmd) { + q->iv->addGridProfile(mPayload, len); + return; + } + record_t<> *rec = q->iv->getRecordStruct(q->cmd); if(NULL == rec) { DPRINTLN(DBG_ERROR, F("record is NULL!")); + closeRequest(q, false); return; } if((rec->pyldLen != len) && (0 != rec->pyldLen)) { diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 34024f0d..1c7d3703 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -11,6 +11,8 @@ #define F(sl) (sl) #endif +#define MAX_GRID_LENGTH 150 + #include "hmDefines.h" #include "HeuristicInv.h" #include "../hms/hmsDefines.h" @@ -131,14 +133,11 @@ class Inverter { bool mGotFragment; // shows if inverter has sent at least one fragment uint8_t curFrmCnt; // count received frames in current loop bool mGotLastMsg; // shows if inverter has already finished transmission cycle - uint8_t mRxChannels; // number of rx channels to listen to, defaults to 3; - uint32_t mRxTmoOuterLoop; // timeout for entire listening loop after sending, defaults to 400 (ms); - uint32_t mRxTmoInnerLoop; // timeout for each listening channel, defaults to 5110 (us) - uint8_t lastCmd; // holds the last sent command, defaults to 0xFF - + uint8_t mCmd; // holds the command to send + bool mIsSingleframeReq; // indicates this is a missing single frame request Radio *radio; // pointer to associated radio class statistics_t radioStatistics; // information about transmitted, failed, ... packets - HeuristicInv heuristics; + HeuristicInv heuristics; // heuristic information / logic uint8_t curCmtFreq; // current used CMT frequency, used to check if freq. was changed during runtime bool commEnabled; // 'pause night communication' sets this field to false @@ -161,11 +160,9 @@ class Inverter { alarmLastId = 0; rssi = -127; miMultiParts = 0; - lastCmd = 0xFF; mGotLastMsg = false; - mRxChannels = 3; - mRxTmoOuterLoop = 400; - mRxTmoInnerLoop = 5110; + mCmd = InitDataState; + mIsSingleframeReq = false; radio = NULL; commEnabled = true; @@ -192,6 +189,8 @@ class Inverter { else if(InitDataState != devControlCmd) { cb(devControlCmd, false); // custom command which was received by API devControlCmd = InitDataState; + } else if((0 == mGridLen) && generalConfig->readGrid) { // read grid profile + cb(GridOnProFilePara, false); } else cb(RealTimeRunData_Debug, false); // get live data } else { @@ -730,6 +729,21 @@ class Inverter { } } + void addGridProfile(uint8_t buf[], uint8_t length) { + mGridLen = (length > MAX_GRID_LENGTH) ? MAX_GRID_LENGTH : length; + std::copy(buf, &buf[mGridLen], mGridProfile); + } + + String getGridProfile(void) { + char buf[MAX_GRID_LENGTH * 3]; + memset(buf, 0, MAX_GRID_LENGTH); + for(uint8_t i = 0; i < mGridLen; i++) { + snprintf(&buf[i*3], 4, "%02X ", mGridProfile[i]); + } + buf[mGridLen*3] = 0; + return String(buf); + } + private: inline void addAlarm(uint16_t code, uint32_t start, uint32_t end) { lastAlarm[alarmNxtWrPos] = alarm_t(code, start, end); @@ -750,6 +764,8 @@ class Inverter { private: float mOffYD[6], mLastYD[6]; bool mDevControlRequest; // true if change needed + uint8_t mGridLen = 0; + uint8_t mGridProfile[MAX_GRID_LENGTH]; }; template diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index fca482ef..5fead045 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -104,50 +104,6 @@ class HmRadio : public Radio { DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring")); } - void prepareReceive(Inverter<> *iv, uint8_t cmd, bool singleframe = false) { - if (singleframe) { - iv->mRxTmoOuterLoop = 65; // SINGLEFR_TIMEOUT - iv->lastCmd = 0xFF; - //DPRINTLN(DBG_INFO, F("1 frm")); - return; - } - - if ( (iv->lastCmd == cmd) || ((iv->ivGen == IV_MI) && (iv->lastCmd != 0xFF)) ) - return; // nothing to be changed.... - - iv->lastCmd = cmd; - if (iv->ivGen != IV_MI) { - if (cmd == RealTimeRunData_Debug) { - if (iv->type == INV_TYPE_4CH) { - iv->mRxChannels = 3; - iv->mRxTmoOuterLoop = 300; - iv->mRxTmoInnerLoop = 5110; - //DPRINTLN(DBG_INFO, F("4ch data")); - } else if (iv->type == INV_TYPE_2CH) { - iv->mRxChannels = 2; - iv->mRxTmoOuterLoop = 250; - iv->mRxTmoInnerLoop = 10220; - //DPRINTLN(DBG_INFO, F("1/2ch data")); - } else { // INV_TYPE_1CH - iv->mRxChannels = 2; - iv->mRxTmoOuterLoop = 400; - iv->mRxTmoInnerLoop = 5110; - } - } else { //3rd gen defaults - iv->mRxChannels = 5; - iv->mRxTmoOuterLoop = 500; - iv->mRxTmoInnerLoop = 5110; - //DPRINTLN(DBG_INFO, F("3rd gen default")); - } - } else { // 2nd gen defaults - iv->mRxChannels = 2; - iv->mRxTmoOuterLoop = 250; - iv->mRxTmoInnerLoop = 5110; - //DPRINTLN(DBG_INFO, F("2nd gen default")); - } - } - - void loop(void) { if (!mIrqRcvd) return; // nothing to do @@ -165,8 +121,9 @@ class HmRadio : public Radio { uint32_t startMicros = micros(); uint32_t loopMillis = millis(); - while ((millis() - loopMillis) < mLastIv->mRxTmoOuterLoop) { - while ((micros() - startMicros) < mLastIv->mRxTmoInnerLoop) { // listen (4088us or?) 5110us to each channel + mRxChIdx = (mTxChIdx + 3) % RF_MAX_CHANNEL_ID; // start with a fixed offset + while ((millis() - loopMillis) < mRxTmoOuterLoop) { + while ((micros() - startMicros) < mRxTmoInnerLoop) { // listen (4088us or?) 5110us to each channel if (mIrqRcvd) { mIrqRcvd = false; @@ -181,7 +138,7 @@ class HmRadio : public Radio { mRxChIdx = 0;*/ //if(++mRxChIdx >= mLastIv->mRxChannels) - if(++mRxChIdx >= mLastIv->mRxChannels) + if(++mRxChIdx >= mRxChannels) mRxChIdx = 0; uint8_t nextRxCh = (mRxChIdx + mTxChIdx + 4) % RF_MAX_CHANNEL_ID; // let 3 channels in shifting out; might cause problems for tx channel 75, see Oberfritze remark to his array @@ -191,8 +148,8 @@ class HmRadio : public Radio { startMicros = micros(); } // not finished but time is over - //if(++mRxChIdx >= RF_CHANNELS) // rejoe2: for testing now always start with the first (relative) rx channel - mRxChIdx = 1; + //if(++mRxChIdx >= RF_CHANNELS) + // mRxChIdx = 0; return; } @@ -287,6 +244,41 @@ class HmRadio : public Radio { sendPacket(iv, cnt, isRetransmit, (IV_MI != iv->ivGen)); } + + void prepareReceive(Inverter<> *iv) { + if (iv->mIsSingleframeReq) { + mRxTmoOuterLoop = 65; // SINGLEFR_TIMEOUT + return; + } + + if (iv->ivGen != IV_MI) { + if (iv->mCmd == RealTimeRunData_Debug) { + if (iv->type == INV_TYPE_4CH) { + mRxChannels = 3; + mRxTmoOuterLoop = 300; + mRxTmoInnerLoop = 5110; + } else if (iv->type == INV_TYPE_2CH) { + mRxChannels = 2; + mRxTmoOuterLoop = 250; + mRxTmoInnerLoop = 10220; + } else { // INV_TYPE_1CH + mRxChannels = 2; + mRxTmoOuterLoop = 200; + mRxTmoInnerLoop = 5110; + } + } else { //3rd gen defaults + mRxChannels = 3; + mRxTmoOuterLoop = iv->mCmd == AlarmData ? 600 : 400; + mRxTmoInnerLoop = 5110; + } + } else { // 2nd gen defaults + mRxChannels = 2; + mRxTmoOuterLoop = 250; + mRxTmoInnerLoop = 5110; + } + } + + uint8_t getDataRate(void) { if(!mNrf24->isChipConnected()) return 3; // unknown @@ -345,6 +337,7 @@ class HmRadio : public Radio { // set TX and RX channels mTxChIdx = mRfChLst[iv->heuristics.txRfChId]; + prepareReceive(iv); if(*mSerialDebug) { DPRINT_IVID(DBG_INFO, iv->id); @@ -359,6 +352,9 @@ class HmRadio : public Radio { else ah::dumpBuf(mTxBuf, len); } else + DBGPRINT(F("0x")); + DHEX(mTxBuf[0]); + DBGPRINT(F(" ")); DBGHEXLN(mTxBuf[9]); } @@ -388,10 +384,14 @@ class HmRadio : public Radio { } uint64_t DTU_RADIO_ID; - uint8_t mRfChLst[RF_CHANNELS] = {03, 23, 40, 61, 75}; // channel List:2403, 2423, 2440, 2461, 2475MHz - uint8_t mTxChIdx = 0; - uint8_t mRxChIdx = 0; - bool mGotLastMsg = false; + uint8_t mRfChLst[RF_CHANNELS] = {03, 23, 40, 61, 75}; // channel List:2403, 2423, 2440, 2461, 2475MHz + uint8_t mTxChIdx = 0; + uint8_t mRxChIdx = 0; + uint8_t mRxChannels = 3; // number of rx channels to listen to, defaults to 3; + uint32_t mRxTmoOuterLoop = 400; // timeout for entire listening loop after sending, defaults to 400 (ms); + uint32_t mRxTmoInnerLoop = 5110; // timeout for each listening channel, defaults to 5110 (us) + uint8_t lastCmd = 0xFF; // holds the last sent command, defaults to 0xFF + bool mGotLastMsg = false; uint32_t mMillis; std::unique_ptr mSpi; diff --git a/src/hm/radio.h b/src/hm/radio.h index 19e891c3..2fe4f640 100644 --- a/src/hm/radio.h +++ b/src/hm/radio.h @@ -22,7 +22,6 @@ class Inverter; class Radio { public: virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) = 0; - virtual void prepareReceive(Inverter<> *iv, uint8_t cmd, bool singleframe = false) = 0; virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; } virtual bool switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) { return true; } virtual bool isChipConnected(void) { return false; } diff --git a/src/hms/cmt2300a.h b/src/hms/cmt2300a.h index bbbeefc7..1ff112e2 100644 --- a/src/hms/cmt2300a.h +++ b/src/hms/cmt2300a.h @@ -6,7 +6,7 @@ #ifndef __CMT2300A_H__ #define __CMT2300A_H__ -#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) +#if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) #include "cmtHal.h" #else #include "esp32_3wSpi.h" @@ -480,7 +480,7 @@ class Cmt2300a { return mSpi.readReg(CMT2300A_CUS_MODE_STA) & CMT2300A_MASK_CHIP_MODE_STA; } - #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(ETHERNET) + #if defined(CONFIG_IDF_TARGET_ESP32S3) && defined(SPI_HAL) cmtHal mSpi; #else esp32_3wSpi mSpi; diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index c7b031e0..40200085 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -26,10 +26,6 @@ class CmtRadio : public Radio { mPrintWholeTrace = printWholeTrace; } - void prepareReceive(Inverter<> *iv, uint8_t cmd, bool singleframe = false) { - return; // only relevant for nRF type inverters - } - void loop() { mCmt.loop(); if((!mIrqRcvd) && (!mRqstGetRx))