diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index b07010ea..a73a3370 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -11,12 +11,13 @@ #include "hmInverter.h" #include "../utils/dbg.h" -#define DEFAULT_ATTEMPS 5 -#define MORE_ATTEMPS_ALARMDATA 3 // 8 -#define MORE_ATTEMPS_GRIDONPROFILEPARA 0 // 5 - template class CommQueue { + protected: /* types */ + static constexpr uint8_t DefaultAttempts = 5; + static constexpr uint8_t MoreAttemptsAlarmData = 3; + static constexpr uint8_t MoreAttemptsGridProfile = 0; + public: CommQueue() : wrPtr {0} @@ -31,7 +32,7 @@ class CommQueue { } void addImportant(Inverter<> *iv, uint8_t cmd) { - queue_s q(iv, cmd, true); + QueueElement q(iv, cmd, true); xSemaphoreTake(this->mutex, portMAX_DELAY); if(!isIncluded(&q)) { dec(&this->rdPtr); @@ -42,7 +43,7 @@ class CommQueue { void add(Inverter<> *iv, uint8_t cmd) { xSemaphoreTake(this->mutex, portMAX_DELAY); - queue_s q(iv, cmd, false); + QueueElement q(iv, cmd, false); if(!isIncluded(&q)) { mQueue[this->wrPtr] = q; inc(&this->wrPtr); @@ -50,12 +51,6 @@ class CommQueue { xSemaphoreGive(this->mutex); } - void chgCmd(Inverter<> *iv, uint8_t cmd) { - xSemaphoreTake(this->mutex, portMAX_DELAY); - mQueue[this->wrPtr] = queue_s(iv, cmd, false); - xSemaphoreGive(this->mutex); - } - uint8_t getFillState(void) const { //DPRINTLN(DBG_INFO, "wr: " + String(this->wrPtr) + ", rd: " + String(this->rdPtr)); return abs(this->rdPtr - this->wrPtr); @@ -66,7 +61,7 @@ class CommQueue { } protected: - struct queue_s { + struct QueueElement { Inverter<> *iv; uint8_t cmd; uint8_t attempts; @@ -74,18 +69,25 @@ class CommQueue { uint32_t ts; bool isDevControl; - queue_s() {} + QueueElement() + : iv {nullptr} + , cmd {0} + , attempts {0} + , attemptsMax {0} + , ts {0} + , isDevControl {false} + {} - queue_s(Inverter<> *i, uint8_t c, bool dev) - : iv {i} - , cmd {c} - , attempts {DEFAULT_ATTEMPS} - , attemptsMax {DEFAULT_ATTEMPS} + QueueElement(Inverter<> *iv, uint8_t cmd, bool devCtrl) + : iv {iv} + , cmd {cmd} + , attempts {DefaultAttempts} + , attemptsMax {DefaultAttempts} , ts {0} - , isDevControl {dev} + , isDevControl {devCtrl} {} - queue_s(const queue_s &other) // copy constructor + QueueElement(const QueueElement &other) // copy constructor : iv {other.iv} , cmd {other.cmd} , attempts {other.attempts} @@ -93,35 +95,48 @@ class CommQueue { , ts {other.ts} , isDevControl {other.isDevControl} {} + + void changeCmd(uint8_t cmd) { + this->cmd = cmd; + this->isDevControl = false; + } + + void setTs(const uint32_t ts) { + this->ts = ts; + } + + void setAttempt() { + if(this->attempts) + this->attempts--; + } + + void incrAttempt(uint8_t attempts = 1) { + this->attempts += attempts; + if (this->attempts > this->attemptsMax) + this->attemptsMax = this->attempts; + } }; protected: - void add(queue_s q) { + void add(QueueElement q) { xSemaphoreTake(this->mutex, portMAX_DELAY); mQueue[this->wrPtr] = q; inc(&this->wrPtr); xSemaphoreGive(this->mutex); } - void add(queue_s *q, bool rstAttempts = false) { + void add(QueueElement *q, bool rstAttempts = false) { xSemaphoreTake(this->mutex, portMAX_DELAY); mQueue[this->wrPtr] = *q; if(rstAttempts) { - mQueue[this->wrPtr].attempts = DEFAULT_ATTEMPS; - mQueue[this->wrPtr].attemptsMax = DEFAULT_ATTEMPS; + mQueue[this->wrPtr].attempts = DefaultAttempts; + mQueue[this->wrPtr].attemptsMax = DefaultAttempts; } inc(&this->wrPtr); xSemaphoreGive(this->mutex); } - void chgCmd(queue_s *q, uint8_t cmd) { - xSemaphoreTake(this->mutex, portMAX_DELAY); - q->cmd = cmd; - q->isDevControl = false; - xSemaphoreGive(this->mutex); - } - - void get(std::function cb) { + void get(std::function cb) { if(this->rdPtr == this->wrPtr) cb(false, nullptr); // empty else { @@ -132,11 +147,11 @@ class CommQueue { } } - void cmdDone(queue_s *q, bool keep = false) { + void cmdDone(QueueElement *q, bool keep = false) { xSemaphoreTake(this->mutex, portMAX_DELAY); if(keep) { - q->attempts = DEFAULT_ATTEMPS; - q->attemptsMax = DEFAULT_ATTEMPS; + q->attempts = DefaultAttempts; + q->attemptsMax = DefaultAttempts; xSemaphoreGive(this->mutex); add(q); // add to the end again xSemaphoreTake(this->mutex, portMAX_DELAY); @@ -145,27 +160,6 @@ class CommQueue { xSemaphoreGive(this->mutex); } - void setTs(queue_s *q, const uint32_t *ts) { - xSemaphoreTake(this->mutex, portMAX_DELAY); - q->ts = *ts; - xSemaphoreGive(this->mutex); - } - - void setAttempt(queue_s *q) { - xSemaphoreTake(this->mutex, portMAX_DELAY); - if(q->attempts) - q->attempts--; - xSemaphoreGive(this->mutex); - } - - void incrAttempt(queue_s *q, uint8_t attempts = 1) { - xSemaphoreTake(this->mutex, portMAX_DELAY); - q->attempts += attempts; - if (q->attempts > q->attemptsMax) - q->attemptsMax = q->attempts; - xSemaphoreGive(this->mutex); - } - private: void inc(uint8_t *ptr) { if(++(*ptr) >= N) @@ -178,7 +172,7 @@ class CommQueue { --(*ptr); } - bool isIncluded(const queue_s *q) { + bool isIncluded(const QueueElement *q) { uint8_t ptr = this->rdPtr; while (ptr != this->wrPtr) { if(mQueue[ptr].cmd == q->cmd) { @@ -193,7 +187,7 @@ class CommQueue { } protected: - std::array mQueue; + std::array mQueue; private: uint8_t wrPtr; diff --git a/src/hm/Communication.h b/src/hm/Communication.h index d60d0d38..1c7c83ae 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -52,7 +52,7 @@ class Communication : public CommQueue<> { } void loop() { - get([this](bool valid, queue_s *q) { + get([this](bool valid, QueueElement *q) { if(!valid) { if(mPrintSequenceDuration) { mPrintSequenceDuration = false; @@ -72,7 +72,7 @@ class Communication : public CommQueue<> { } private: - inline void innerLoop(queue_s *q) { + inline void innerLoop(QueueElement *q) { switch(mState) { case States::RESET: if (!mWaitTime.isTimeout()) @@ -102,13 +102,13 @@ class Communication : public CommQueue<> { mFramesExpected = getFramesExpected(q); // function to get expected frame count. mTimeout = DURATION_TXFRAME + mFramesExpected*DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]; if((q->iv->ivGen == IV_MI) && ((q->cmd == MI_REQ_CH1) || (q->cmd == MI_REQ_4CH))) - incrAttempt(q, q->iv->channels); // 2 more attempts for 2ch, 4 more for 4ch + q->incrAttempt(q->iv->channels); // 2 more attempts for 2ch, 4 more for 4ch mState = States::START; break; case States::START: - setTs(q, mTimestamp); + q->setTs(*mTimestamp); if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) { // frequency was changed during runtime if(q->iv->curCmtFreq != q->iv->config->frequency) { @@ -127,10 +127,10 @@ class Communication : public CommQueue<> { //q->iv->radioStatistics.txCnt++; q->iv->radio->mRadioWaitTime.startTimeMonitor(mTimeout); if((!mIsRetransmit && (q->cmd == AlarmData)) || (q->cmd == GridOnProFilePara)) - incrAttempt(q, (q->cmd == AlarmData)? MORE_ATTEMPS_ALARMDATA : MORE_ATTEMPS_GRIDONPROFILEPARA); + q->incrAttempt((q->cmd == AlarmData)? CommQueue::MoreAttemptsAlarmData : CommQueue::MoreAttemptsGridProfile); mIsRetransmit = false; - setAttempt(q); + q->setAttempt(); mState = States::WAIT; break; @@ -292,7 +292,7 @@ class Communication : public CommQueue<> { } } - setAttempt(q); + q->setAttempt(); if(*mSerialDebug) { DPRINT_IVID(DBG_WARN, q->iv->id); @@ -321,7 +321,7 @@ class Communication : public CommQueue<> { } } - inline void printRxInfo(queue_s *q, packet_t *p) { + inline void printRxInfo(QueueElement *q, packet_t *p) { DPRINT_IVID(DBG_INFO, q->iv->id); DBGPRINT(F("RX ")); if(p->millis < 100) @@ -355,7 +355,7 @@ class Communication : public CommQueue<> { } - inline uint8_t getFramesExpected(queue_s *q) { + inline uint8_t getFramesExpected(QueueElement *q) { if(q->isDevControl) return 1; @@ -419,7 +419,7 @@ class Communication : public CommQueue<> { return (ah::crc8(buf, len - 1) == buf[len-1]); } - inline bool parseFrame(queue_s *q, packet_t *p) { + inline bool parseFrame(QueueElement *q, packet_t *p) { uint8_t *frameId = &p->packet[9]; if(0x00 == *frameId) { DPRINTLN(DBG_WARN, F("invalid frameId 0x00")); @@ -438,7 +438,7 @@ class Communication : public CommQueue<> { if((*frameId & ALL_FRAMES) == ALL_FRAMES) { mMaxFrameId = (*frameId & 0x7f); if(mMaxFrameId > 8) // large payloads, e.g. AlarmData - incrAttempt(q, mMaxFrameId - 6); + q->incrAttempt(mMaxFrameId - 6); } frame_t *f = &mLocalBuf[(*frameId & 0x7f) - 1]; @@ -449,7 +449,7 @@ class Communication : public CommQueue<> { return true; } - inline void parseMiFrame(packet_t *p, queue_s *q) { + inline void parseMiFrame(packet_t *p, QueueElement *q) { if((!mIsRetransmit && p->packet[9] == 0x00) && (p->millis < LIMIT_FAST_IV_MI)) //first frame is fast? mHeu.setIvRetriesGood(q->iv,p->millis < LIMIT_VERYFAST_IV_MI); if ((p->packet[0] == MI_REQ_CH1 + ALL_FRAMES) @@ -473,7 +473,7 @@ class Communication : public CommQueue<> { } } - inline bool parseDevCtrl(const packet_t *p, queue_s *q) { + inline bool parseDevCtrl(const packet_t *p, QueueElement *q) { switch(p->packet[12]) { case ActivePowerContr: if(p->packet[13] != 0x00) @@ -511,7 +511,7 @@ class Communication : public CommQueue<> { return accepted; } - inline bool compilePayload(queue_s *q) { + inline bool compilePayload(QueueElement *q) { uint16_t crc = 0xffff, crcRcv = 0x0000; for(uint8_t i = 0; i < mMaxFrameId; i++) { if(i == (mMaxFrameId - 1)) { @@ -611,7 +611,7 @@ class Communication : public CommQueue<> { return true; } - void sendRetransmit(queue_s *q, uint8_t i) { + void sendRetransmit(QueueElement *q, uint8_t i) { mFramesExpected = 1; q->iv->radio->setExpectedFrames(mFramesExpected); q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + i), true); @@ -622,7 +622,7 @@ class Communication : public CommQueue<> { } private: - void closeRequest(queue_s *q, bool crcPass) { + void closeRequest(QueueElement *q, bool crcPass) { mHeu.evalTxChQuality(q->iv, crcPass, (q->attemptsMax - 1 - q->attempts), q->iv->curFrmCnt); if(crcPass) q->iv->radioStatistics.rxSuccess++; @@ -646,7 +646,7 @@ class Communication : public CommQueue<> { DBGPRINTLN(F("-----")); } - inline void miHwDecode(packet_t *p, queue_s *q) { + inline void miHwDecode(packet_t *p, QueueElement *q) { record_t<> *rec = q->iv->getRecordStruct(InverterDevInform_All); // choose the record structure rec->ts = q->ts; /* @@ -760,7 +760,7 @@ class Communication : public CommQueue<> { } } - inline void miGPFDecode(packet_t *p, queue_s *q) { + inline void miGPFDecode(packet_t *p, QueueElement *q) { record_t<> *rec = q->iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure rec->ts = q->ts; rec->mqttSentStatus = MqttSentStatus::NEW_DATA; @@ -786,7 +786,7 @@ class Communication : public CommQueue<> { q->iv->miMultiParts = 7; // indicate we are ready } - inline void miDataDecode(packet_t *p, queue_s *q) { + inline void miDataDecode(packet_t *p, QueueElement *q) { record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser rec->ts = q->ts; //mState = States::RESET; @@ -839,7 +839,7 @@ class Communication : public CommQueue<> { q->iv->miMultiParts += 6; // indicate we are ready } - void miNextRequest(uint8_t cmd, queue_s *q) { + void miNextRequest(uint8_t cmd, QueueElement *q) { mHeu.evalTxChQuality(q->iv, true, (q->attemptsMax - 1 - q->attempts), q->iv->curFrmCnt); mHeu.getTxCh(q->iv); q->iv->radioStatistics.ivSent++; @@ -859,12 +859,12 @@ class Communication : public CommQueue<> { DBGHEXLN(cmd); } mIsRetransmit = true; - chgCmd(q, cmd); + q->changeCmd(cmd); //mState = States::WAIT; } - void miRepeatRequest(queue_s *q) { - setAttempt(q); // if function is called, we got something, and we necessarily need more transmissions for MI types... + void miRepeatRequest(QueueElement *q) { + q->setAttempt(); // if function is called, we got something, and we necessarily need more transmissions for MI types... q->iv->radio->sendCmdPacket(q->iv, q->cmd, 0x00, true); q->iv->radioStatistics.retransmits++; q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]); @@ -878,7 +878,7 @@ class Communication : public CommQueue<> { //mIsRetransmit = false; } - void miStsConsolidate(queue_s *q, uint8_t stschan, record_t<> *rec, uint8_t uState, uint8_t uEnum, uint8_t lState = 0, uint8_t lEnum = 0) { + void miStsConsolidate(QueueElement *q, uint8_t stschan, record_t<> *rec, uint8_t uState, uint8_t uEnum, uint8_t lState = 0, uint8_t lEnum = 0) { //uint8_t status = (p->packet[11] << 8) + p->packet[12]; uint16_t statusMi = 3; // regular status for MI, change to 1 later? if ( uState == 2 ) {