From 5b3d0593fe8da30618958711fcf2611d2ccb18af Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Wed, 18 Oct 2023 18:56:59 +0200 Subject: [PATCH] some more MI specific things - might decode data and enqueue correct next command - small fixes wrt. to serial readibility --- src/hm/CommQueue.h | 16 +++++++ src/hm/Communication.h | 105 ++++++++++++++++++++++++++++++++++++++++- src/hm/hmInverter.h | 3 +- src/hm/hmRadio.h | 3 +- 4 files changed, 124 insertions(+), 3 deletions(-) diff --git a/src/hm/CommQueue.h b/src/hm/CommQueue.h index 9c9da707..5f27db60 100644 --- a/src/hm/CommQueue.h +++ b/src/hm/CommQueue.h @@ -22,6 +22,10 @@ class CommQueue { void add(Inverter<> *iv, uint8_t cmd, bool delOnPop = true) { mQueue[mWrPtr] = queue_s(iv, cmd, delOnPop, false); + /*mQueue[mRdPtr].firstTry = false; + if((IV_HM == mQueue[mRdPtr].iv->ivGen) || (IV_MI == mQueue[mRdPtr].iv->ivGen)) { + mQueue[mRdPtr].firstTry = ((mQueue[mRdPtr].iv->isAvailable()) || (millis() < 120000)); + }*/ inc(&mWrPtr); } @@ -32,6 +36,7 @@ class CommQueue { uint8_t attempts; bool delOnPop; bool isDevControl; + bool firstTry; uint32_t ts; queue_s() {} queue_s(Inverter<> *i, uint8_t c, bool d, bool dev) : @@ -41,6 +46,10 @@ class CommQueue { protected: void add(queue_s q) { mQueue[mWrPtr] = q; + /*mQueue[mRdPtr].firstTry = false; + if((IV_HM == mQueue[mRdPtr].iv->ivGen) || (IV_MI == mQueue[mRdPtr].iv->ivGen)) { + mQueue[mRdPtr].firstTry = ((mQueue[mRdPtr].iv->isAvailable()) || (millis() < 120000)); + }*/ inc(&mWrPtr); } @@ -60,6 +69,13 @@ class CommQueue { inc(&mRdPtr); } + bool isFirstTry(void) { + if(!mQueue[mRdPtr].firstTry) + return false; + mQueue[mRdPtr].firstTry = false; + return true; + } + void setTs(uint32_t *ts) { mQueue[mRdPtr].ts = *ts; } diff --git a/src/hm/Communication.h b/src/hm/Communication.h index c14bd4f0..2dbf4593 100644 --- a/src/hm/Communication.h +++ b/src/hm/Communication.h @@ -90,6 +90,13 @@ class Communication : public CommQueue<> { case States::CHECK_FRAMES: { if(!q->iv->radio->get()) { // radio buffer empty + // second try for nRF type inverters if available + /*if(isFirstTry()) { + DPRINT_IVID(DBG_INFO, q->iv->id); + DBGPRINTLN(F("enqueue second try")); + mState = States::START; + break; + }*/ cmdDone(); DPRINT_IVID(DBG_INFO, q->iv->id); DBGPRINT(F("request timeout: ")); @@ -111,12 +118,17 @@ class Communication : public CommQueue<> { DPRINT_IVID(DBG_INFO, q->iv->id); DBGPRINT(F("RX ")); + if(p->millis<100) + DBGPRINT("0"); DBGPRINT(String(p->millis)); DBGPRINT(F("ms ")); DBGPRINT(String(p->len)); if((IV_HM == q->iv->ivGen) || (IV_MI == q->iv->ivGen)) { DBGPRINT(F(" CH")); - DBGPRINT(String(p->ch)); + if(p->ch == 3) + DBGPRINT("03"); + else + DBGPRINT(String(p->ch)); } DBGPRINT(F(", ")); DBGPRINT(String(p->rssi)); @@ -132,6 +144,23 @@ class Communication : public CommQueue<> { } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command parseDevCtrl(p, q); cmdDone(true); // remove done request + } else if (q->iv->ivGen == IV_MI) { + /*if (p->packet[0] == (0x88)) { // 0x88 is MI status response to 0x09 + miStsDecode(p, q); + } + + else if (p->packet[0] == (MI_REQ_CH2 + SINGLE_FRAME)) { // 0x92; MI status response to 0x11 + miStsDecode(p, q, CH2); + + } else*/ 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) && p->packet[0] < (0x39 + SINGLE_FRAME) + && q->cmd != 0x0f) ) { // small MI or MI 1500 data responses to 0x09, 0x11, 0x36, 0x37, 0x38 and 0x39 + //mPayload[iv->id].txId = p->packet[0]; + miDataDecode(p, q); + + } + //parseMiFrame(p, q); } } @@ -254,6 +283,80 @@ class Communication : public CommQueue<> { q->iv->actPowerLimit = 0xffff; // unknown, readback current value } + inline void parseMiFrame(packet_t *p, const queue_s *q) { + if((p->packet[12] != ActivePowerContr) || (p->packet[13] != 0x00)) + return; + bool accepted = true; + if((p->packet[10] == 0x00) && (p->packet[11] == 0x00)) + q->iv->powerLimitAck = true; + else + accepted = false; + + DPRINT_IVID(DBG_INFO, q->iv->id); + DBGPRINT(F("has ")); + if(!accepted) DBGPRINT(F("not ")); + DBGPRINT(F("accepted power limit set point ")); + DBGPRINT(String(q->iv->powerLimit[0])); + DBGPRINT(F(" with PowerLimitControl ")); + DBGPRINTLN(String(q->iv->powerLimit[1])); + q->iv->actPowerLimit = 0xffff; // unknown, readback current value + } + + inline void miDataDecode(packet_t *p, const queue_s *q) { + record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser + //rec->ts = mPayload[iv->id].ts; + //mPayload[iv->id].gotFragment = true; + //mPayload[iv->id].multi_parts += 4; + + uint8_t datachan = ( p->packet[0] == (MI_REQ_CH1 + ALL_FRAMES) || p->packet[0] == (MI_REQ_4CH + ALL_FRAMES) ) ? CH1 : + ( p->packet[0] == (MI_REQ_CH2 + ALL_FRAMES) || p->packet[0] == (0x37 + ALL_FRAMES) ) ? CH2 : + p->packet[0] == (0x38 + ALL_FRAMES) ? CH3 : + CH4; + // count in RF_communication_protocol.xlsx is with offset = -1 + q->iv->setValue(q->iv->getPosByChFld(datachan, FLD_UDC, rec), rec, (float)((p->packet[9] << 8) + p->packet[10])/10); + yield(); + q->iv->setValue(q->iv->getPosByChFld(datachan, FLD_IDC, rec), rec, (float)((p->packet[11] << 8) + p->packet[12])/10); + yield(); + q->iv->setValue(q->iv->getPosByChFld(0, FLD_UAC, rec), rec, (float)((p->packet[13] << 8) + p->packet[14])/10); + yield(); + q->iv->setValue(q->iv->getPosByChFld(0, FLD_F, rec), rec, (float) ((p->packet[15] << 8) + p->packet[16])/100); + q->iv->setValue(q->iv->getPosByChFld(datachan, FLD_PDC, rec), rec, (float)((p->packet[17] << 8) + p->packet[18])/10); + yield(); + q->iv->setValue(q->iv->getPosByChFld(datachan, FLD_YD, rec), rec, (float)((p->packet[19] << 8) + p->packet[20])/1); + yield(); + q->iv->setValue(q->iv->getPosByChFld(0, FLD_T, rec), rec, (float) ((int16_t)(p->packet[21] << 8) + p->packet[22])/10); + q->iv->setValue(q->iv->getPosByChFld(0, FLD_IRR, rec), rec, (float) (calcIrradiation(q->iv, datachan))); + //mPayload[q->iv->id].rssi[(datachan-1)] = p->rssi; + + /*if ( datachan < 3 ) { + mPayload[q->iv->id].dataAB[datachan] = true; + } + if ( !mPayload[iv->id].dataAB[CH0] && mPayload[iv->id].dataAB[CH1] && mPayload[iv->id].dataAB[CH2] ) { + mPayload[iv->id].dataAB[CH0] = true; + }*/ + + if (p->packet[0] >= (MI_REQ_4CH + ALL_FRAMES) ) { + /*For MI1500: + if (MI1500) { + STAT = (uint8_t)(p->packet[25] ); + FCNT = (uint8_t)(p->packet[26]); + FCODE = (uint8_t)(p->packet[27]); + }*/ + //miStsConsolidate(iv, datachan, rec, p->packet[23], p->packet[24]); + + if (p->packet[0] < (0x39 + ALL_FRAMES) ) { + addImportant(q->iv, (q->cmd + 1)); + //mPayload[iv->id].txCmd++; + //mPayload[iv->id].retransmits = 0; // reserve retransmissions for each response + //mPayload[iv->id].complete = false; + } else { + //miComplete(iv); + } + } else if((p->packet[0] == (MI_REQ_CH1 + ALL_FRAMES)) && q->iv->type == INV_TYPE_2CH ) { + addImportant(q->iv, MI_REQ_CH2); + } + } + inline void compilePayload(const queue_s *q) { uint16_t crc = 0xffff, crcRcv = 0x0000; for(uint8_t i = 0; i < mMaxFrameId; i++) { diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 04aca4d2..e90acac3 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -202,7 +202,8 @@ class Inverter { mDevControlRequest = false; } else if(0 == getFwVersion()) - cb(InverterDevInform_All, false); // get firmware version + cb(MI_REQ_CH1, false); // get firmware version + //cb(InverterDevInform_All, false); // get firmware version else { record_t<> *rec = getRecordStruct(InverterDevInform_Simple); if (getChannelFieldValue(CH0, FLD_PART_NUM, rec) == 0) diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 461fd08e..e8a95990 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -146,7 +146,8 @@ class HmRadio : public Radio { } void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, uint16_t powerMax = 0) { - DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x")); + DPRINT_IVID(DBG_INFO,iv->id); + DBGPRINT(F("sendControlPacket cmd: 0x")); DBGHEXLN(cmd); initPacket(iv->radioId.u64, TX_REQ_DEVCONTROL, SINGLE_FRAME); uint8_t cnt = 10;