From 09896fbe6be78e645c9bb76e88203adc3492bdd3 Mon Sep 17 00:00:00 2001 From: lumapu Date: Fri, 29 Sep 2023 23:54:29 +0200 Subject: [PATCH] first comparison, compiles fine --- src/hm/hmPayload.h | 3 +- src/hms/hmsPayload.h | 233 ++++++++++++++++++++++++++++--------------- src/hms/hmsRadio.h | 5 + 3 files changed, 158 insertions(+), 83 deletions(-) diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index 8693cb00..a07c57eb 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // 2023 Ahoy, https://ahoydtu.de -// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/ +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed //----------------------------------------------------------------------------- #ifndef __HM_PAYLOAD_H__ @@ -15,7 +15,6 @@ typedef struct { uint8_t txCmd; uint8_t txId; - uint8_t invId; uint32_t ts; uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; int8_t rssi[MAX_PAYLOAD_ENTRIES]; diff --git a/src/hms/hmsPayload.h b/src/hms/hmsPayload.h index e082f059..489fe044 100644 --- a/src/hms/hmsPayload.h +++ b/src/hms/hmsPayload.h @@ -16,7 +16,6 @@ typedef struct { uint8_t txCmd; uint8_t txId; - //uint8_t invId; uint32_t ts; uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; int8_t rssi[MAX_PAYLOAD_ENTRIES]; @@ -27,6 +26,7 @@ typedef struct { uint8_t retransmits; bool requested; bool gotFragment; + bool rxTmo; } hmsPayload_t; @@ -50,11 +50,10 @@ class HmsPayload { reset(i); mIvCmd56Cnt[i] = 0; } - mSerialDebug = false; - mHighPrioIv = NULL; - mCbAlarm = NULL; - mCbPayload = NULL; - //mLastRx = 0; + mSerialDebug = false; + mHighPrioIv = NULL; + mCbAlarm = NULL; + mCbPayload = NULL; } void enableSerialDebug(bool enable) { @@ -70,12 +69,35 @@ class HmsPayload { } void loop() { - if(NULL != mHighPrioIv) { + if (NULL != mHighPrioIv) { ivSend(mHighPrioIv, true); mHighPrioIv = NULL; } } + /*void simulation() { + uint8_t pay[] = { + 0x00, 0x01, 0x01, 0x24, 0x02, 0x28, 0x02, 0x33, + 0x06, 0x49, 0x06, 0x6a, 0x00, 0x05, 0x5f, 0x1b, + 0x00, 0x06, 0x66, 0x9a, 0x03, 0xfd, 0x04, 0x0b, + 0x01, 0x23, 0x02, 0x28, 0x02, 0x28, 0x06, 0x41, + 0x06, 0x43, 0x00, 0x05, 0xdc, 0x2c, 0x00, 0x06, + 0x2e, 0x3f, 0x04, 0x01, 0x03, 0xfb, 0x09, 0x78, + 0x13, 0x86, 0x18, 0x15, 0x00, 0xcf, 0x00, 0xfe, + 0x03, 0xe7, 0x01, 0x42, 0x00, 0x03 + }; + + Inverter<> *iv = mSys->getInverterByPos(0); + record_t<> *rec = iv->getRecordStruct(0x0b); + rec->ts = *mTimestamp; + for (uint8_t i = 0; i < rec->length; i++) { + iv->addValue(i, pay, rec); + yield(); + } + iv->doCalculations(); + notify(0x0b, iv); + }*/ + void ivSendHighPrio(Inverter<> *iv) { mHighPrioIv = iv; } @@ -90,26 +112,26 @@ class HmsPayload { process(false); // no retransmit if (!mPayload[iv->id].complete) { - if (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId) + if (mSerialDebug) + DPRINT_IVID(DBG_INFO, iv->id); + if (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId) { mStat->rxFailNoAnser++; // got nothing - else + if (mSerialDebug) + DBGPRINTLN(F("enqueued cmd failed/timeout")); + } else { mStat->rxFail++; // got fragments but not complete response - + if (mSerialDebug) { + DBGPRINT(F("no complete Payload received! (retransmits: ")); + DBGPRINT(String(mPayload[iv->id].retransmits)); + DBGPRINTLN(F(")")); + } + } iv->setQueuedCmdFinished(); // command failed - if (mSerialDebug) - DPRINTLN(DBG_INFO, F("enqueued cmd failed/timeout")); - /*if (mSerialDebug) { - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(") no Payload received! (retransmits: ")); - DBGPRINT(String(mPayload[iv->id].retransmits)); - DBGPRINTLN(F(")")); - }*/ } } } - reset(iv->id); + reset(iv->id, !iv->isAvailable()); mPayload[iv->id].requested = true; yield(); @@ -140,9 +162,11 @@ class HmsPayload { if(++mIvCmd56Cnt[iv->id] == 10) mIvCmd56Cnt[iv->id] = 0; uint8_t cmd = iv->getQueuedCmd(); - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F("prepareDevInformCmd 0x")); - DBGHEXLN(cmd); + if (mSerialDebug) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("prepareDevInformCmd 0x")); + DBGHEXLN(cmd); + } mRadio->prepareDevInformCmd(&iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); mPayload[iv->id].txCmd = cmd; } @@ -154,7 +178,7 @@ class HmsPayload { DPRINTLN(DBG_DEBUG, F("Response from info request received")); uint8_t *pid = &p->data[10]; if (*pid == 0x00) { - DPRINT(DBG_DEBUG, F("fragment number zero received and ignored")); + DPRINTLN(DBG_DEBUG, F("fragment number zero received and ignored")); } else { DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX)); if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) { @@ -186,13 +210,16 @@ class HmsPayload { iv->powerLimitAck = true; } else ok = false; - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINT(F(" has ")); - if(!ok) DBGPRINT(F("not ")); - DBGPRINT(F("accepted power limit set point ")); - DBGPRINT(String(iv->powerLimit[0])); - DBGPRINT(F(" with PowerLimitControl ")); - DBGPRINTLN(String(iv->powerLimit[1])); + + if (mSerialDebug) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F(" has ")); + if(!ok) DBGPRINT(F("not ")); + DBGPRINT(F("accepted power limit set point ")); + DBGPRINT(String(iv->powerLimit[0])); + DBGPRINT(F(" with PowerLimitControl ")); + DBGPRINTLN(String(iv->powerLimit[1])); + } iv->clearCmdQueue(); iv->enqueCommand(SystemConfigPara); // read back power limit @@ -219,8 +246,9 @@ class HmsPayload { } if (!mPayload[iv->id].complete) { - bool crcPass, pyldComplete; - crcPass = build(iv->id, &pyldComplete); + bool crcPass, pyldComplete, fastNext; + + crcPass = build(iv, &pyldComplete, &fastNext); if (!crcPass && !pyldComplete) { // payload not complete if ((mPayload[iv->id].requested) && (retransmit)) { if (mPayload[iv->id].retransmits < mMaxRetrans) { @@ -230,26 +258,31 @@ class HmsPayload { DPRINTLN(DBG_INFO, F("Prevent retransmit on Restart / CleanState_LockAndAlarm...")); mPayload[iv->id].retransmits = mMaxRetrans; } else if(iv->devControlCmd == ActivePowerContr) { + DPRINT_IVID(DBG_INFO, iv->id); DPRINTLN(DBG_INFO, F("retransmit power limit")); mRadio->sendControlPacket(&iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); } else { if(false == mPayload[iv->id].gotFragment) { - - //DPRINTLN(DBG_WARN, F("nothing received: Request Complete Retransmit")); - //mPayload[iv->id].txCmd = iv->getQueuedCmd(); - //DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); - //mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); - - DPRINT_IVID(DBG_INFO, iv->id); - DBGPRINTLN(F("nothing received")); - mPayload[iv->id].retransmits = mMaxRetrans; + DPRINT_IVID(DBG_WARN, iv->id); + if (mPayload[iv->id].rxTmo) { + DBGPRINTLN(F("nothing received")); + mPayload[iv->id].retransmits = mMaxRetrans; + } else { + DBGPRINTLN(F("nothing received: complete retransmit")); + mPayload[iv->id].txCmd = iv->getQueuedCmd(); + DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); + mRadio->prepareDevInformCmd(&iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); + } } else { for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { if (mPayload[iv->id].len[i] == 0) { - DPRINT(DBG_WARN, F("Frame ")); - DBGPRINT(String(i + 1)); - DBGPRINTLN(F(" missing: Request Retransmit")); - //mRadio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); + if (mSerialDebug) { + DPRINT_IVID(DBG_WARN, iv->id); + DBGPRINT(F("Frame ")); + DBGPRINT(String(i + 1)); + DBGPRINTLN(F(" missing: Request Retransmit")); + } + mRadio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); break; // only request retransmit one frame per loop } yield(); @@ -257,26 +290,36 @@ class HmsPayload { } } } + } else if (false == mPayload[iv->id].gotFragment) { + // only if there is no sign of life + mPayload[iv->id].rxTmo = true; // inv might be down, no complete retransmit anymore } - } /*else if(!crcPass && pyldComplete) { // crc error on complete Payload + } else if(!crcPass && pyldComplete) { // crc error on complete Payload if (mPayload[iv->id].retransmits < mMaxRetrans) { mPayload[iv->id].retransmits++; - DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit")); mPayload[iv->id].txCmd = iv->getQueuedCmd(); - DPRINT(DBG_INFO, F("(#")); - DBGPRINT(String(iv->id)); - DBGPRINT(F(") prepareDevInformCmd 0x")); - DBGPRINTLN(String(mPayload[iv->id].txCmd, HEX)); - mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); + if (mSerialDebug) { + DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit")); + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("prepareDevInformCmd 0x")); + DBGHEXLN(mPayload[iv->id].txCmd); + } + mRadio->prepareDevInformCmd(&iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); + } + } else { // payload complete + if (mSerialDebug) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("procPyld: cmd: 0x")); + DBGHEXLN(mPayload[iv->id].txCmd); + //DPRINT(DBG_DEBUG, F("procPyld: txid: 0x")); + //DBGHEXLN(mPayload[iv->id].txId); + DPRINT(DBG_DEBUG, F("procPyld: max: ")); + DPRINTLN(DBG_DEBUG, String(mPayload[iv->id].maxPackId)); } - }*/ else { // payload complete - DPRINT(DBG_INFO, F("procPyld: cmd: 0x")); - DBGPRINTLN(String(mPayload[iv->id].txCmd, HEX)); - //DPRINT(DBG_DEBUG, F("procPyld: txid: 0x")); - //DBGPRINTLN(String(mPayload[iv->id].txId, HEX)); - DPRINTLN(DBG_DEBUG, F("procPyld: max: ") + String(mPayload[iv->id].maxPackId)); record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser mPayload[iv->id].complete = true; + mPayload[iv->id].requested = false; + mPayload[iv->id].rxTmo = false; uint8_t payload[150]; uint8_t payloadLen = 0; @@ -324,7 +367,6 @@ class HmsPayload { if(AlarmData == mPayload[iv->id].txCmd) { uint8_t i = 0; - uint32_t start, end; while(1) { if(0 == iv->parseAlarmLog(i++, payload, payloadLen)) break; @@ -333,10 +375,28 @@ class HmsPayload { yield(); } } + if (fastNext && (mHighPrioIv == NULL)) { + /*iv->setQueuedCmdFinished(); + uint8_t cmd = iv->getQueuedCmd(); + if (mSerialDebug) { + DPRINT_IVID(DBG_INFO, iv->id); + DBGPRINT(F("fast mode ")); + DBGPRINT(F("prepareDevInformCmd 0x")); + DBGHEXLN(cmd); + } + mStat->rxSuccess++; + mRadio->prepareDevInformCmd(&iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); + mPayload[iv->id].txCmd = cmd; + */ + mHighPrioIv = iv; + } + } else { - DPRINT(DBG_ERROR, F("plausibility check failed, expected ")); - DBGPRINT(String(rec->pyldLen)); - DBGPRINTLN(F(" bytes")); + if (mSerialDebug) { + DPRINT(DBG_ERROR, F("plausibility check failed, expected ")); + DBGPRINT(String(rec->pyldLen)); + DBGPRINTLN(F(" bytes")); + } mStat->rxFail++; } @@ -353,47 +413,59 @@ class HmsPayload { (mCbPayload)(val, iv); } - bool build(uint8_t id, bool *complete) { + bool build(Inverter<> *iv, bool *complete, bool *fastNext ) { DPRINTLN(DBG_VERBOSE, F("build")); uint16_t crc = 0xffff, crcRcv = 0x0000; - if (mPayload[id].maxPackId > MAX_PAYLOAD_ENTRIES) - mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; + if (mPayload[iv->id].maxPackId > MAX_PAYLOAD_ENTRIES) + mPayload[iv->id].maxPackId = MAX_PAYLOAD_ENTRIES; // check if all fragments are there *complete = true; - for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) { - if(mPayload[id].len[i] == 0) + *fastNext = false; + for (uint8_t i = 0; i < mPayload[iv->id].maxPackId; i++) { + if(mPayload[iv->id].len[i] == 0) { *complete = false; + } } if(!*complete) return false; - for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) { - if (mPayload[id].len[i] > 0) { - if (i == (mPayload[id].maxPackId - 1)) { - crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i] - 1, crc); - crcRcv = (mPayload[id].data[i][mPayload[id].len[i] - 2] << 8) | (mPayload[id].data[i][mPayload[id].len[i] - 1]); + for (uint8_t i = 0; i < mPayload[iv->id].maxPackId; i++) { + if (mPayload[iv->id].len[i] > 0) { + if (i == (mPayload[iv->id].maxPackId - 1)) { + crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->id].len[i] - 1, crc); + crcRcv = (mPayload[iv->id].data[i][mPayload[iv->id].len[i] - 2] << 8) | (mPayload[iv->id].data[i][mPayload[iv->id].len[i] - 1]); } else - crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i], crc); + crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->id].len[i], crc); } yield(); } - return (crc == crcRcv) ? true : false; + //return (crc == crcRcv) ? true : false; + if (crc != crcRcv) + return false; + + //requests to cause the next request to be executed immediately + if (mPayload[iv->id].gotFragment && ((mPayload[iv->id].txCmd < 11) || (mPayload[iv->id].txCmd > 18))) { + *fastNext = true; + } + + return true; } - void reset(uint8_t id) { - //DPRINT(DBG_INFO, "resetPayload: id: "); - //DBGPRINTLN(String(id)); - memset(&mPayload[id], 0, sizeof(hmsPayload_t)); + void reset(uint8_t id, bool setTxTmo = true) { + //DPRINT_IVID(DBG_INFO, id); + //DBGPRINTLN(F("resetPayload")); + memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); mPayload[id].txCmd = 0; mPayload[id].gotFragment = false; - //mPayload[id].retransmits = 0; + mPayload[id].retransmits = 0; mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; mPayload[id].lastFound = false; mPayload[id].complete = false; mPayload[id].requested = false; mPayload[id].ts = *mTimestamp; + mPayload[id].rxTmo = setTxTmo; // design: don't start with complete retransmit } IApp *mApp; @@ -402,7 +474,6 @@ class HmsPayload { statistics_t *mStat; uint8_t mMaxRetrans; uint32_t *mTimestamp; - //uint32_t mLastRx; hmsPayload_t mPayload[MAX_NUM_INVERTERS]; uint8_t mIvCmd56Cnt[MAX_NUM_INVERTERS]; bool mSerialDebug; diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index e579deda..4cc88d03 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -111,6 +111,11 @@ class CmtRadio { sendPacket(24, isRetransmit); } + void sendCmdPacket(uint64_t ivId, uint8_t mid, uint8_t pid, bool isRetransmit) { + initPacket(&ivId, mid, pid); + sendPacket(10, isRetransmit); + } + void sendPacket(uint8_t len, bool isRetransmit) { if (len > 14) { uint16_t crc = ah::crc16(&mTxBuf[10], len - 10);