Browse Source

moved radio-statistic to inverter (not global per radio module any more)

pull/1197/head
lumapu 1 year ago
parent
commit
ac0a4976d8
  1. 8
      src/app.cpp
  2. 2
      src/app.h
  3. 5
      src/hm/hmInverter.h
  4. 30
      src/hm/hmPayload.h
  5. 32
      src/hm/hmRadio.h
  6. 42
      src/hm/miPayload.h
  7. 12
      src/hm/radio.h
  8. 38
      src/hms/hmsRadio.h

8
src/app.cpp

@ -34,12 +34,12 @@ void app::setup() {
DBGPRINTLN(F("false")); DBGPRINTLN(F("false"));
if(mConfig->nrf.enabled) { if(mConfig->nrf.enabled) {
mNrfRadio.setup(&mNrfStat, mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs, mConfig->nrf.pinSclk, mConfig->nrf.pinMosi, mConfig->nrf.pinMiso); mNrfRadio.setup(mConfig->nrf.amplifierPower, mConfig->nrf.pinIrq, mConfig->nrf.pinCe, mConfig->nrf.pinCs, mConfig->nrf.pinSclk, mConfig->nrf.pinMosi, mConfig->nrf.pinMiso);
mNrfRadio.enableDebug(); mNrfRadio.enableDebug();
} }
#if defined(ESP32) #if defined(ESP32)
if(mConfig->cmt.enabled) { if(mConfig->cmt.enabled) {
mCmtRadio.setup(&mCmtStat, mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb, false); mCmtRadio.setup(mConfig->cmt.pinSclk, mConfig->cmt.pinSdio, mConfig->cmt.pinCsb, mConfig->cmt.pinFcsb, false);
mCmtRadio.enableDebug(); mCmtRadio.enableDebug();
} }
#endif #endif
@ -71,11 +71,11 @@ void app::setup() {
}); });
} }
mPayload.setup(this, &mSys, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mPayload.setup(this, &mSys, mConfig->nrf.maxRetransPerPyld, &mTimestamp);
mPayload.enableSerialDebug(mConfig->serial.debug); mPayload.enableSerialDebug(mConfig->serial.debug);
mPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); mPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2));
if (mConfig->nrf.enabled) { if (mConfig->nrf.enabled) {
mMiPayload.setup(this, &mSys, &mNrfRadio, &mNrfStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mMiPayload.setup(this, &mSys, mConfig->nrf.maxRetransPerPyld, &mTimestamp);
mMiPayload.enableSerialDebug(mConfig->serial.debug); mMiPayload.enableSerialDebug(mConfig->serial.debug);
mMiPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2)); mMiPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1, std::placeholders::_2));
} }

2
src/app.h

@ -42,7 +42,7 @@
typedef HmSystem<MAX_NUM_INVERTERS> HmSystemType; typedef HmSystem<MAX_NUM_INVERTERS> HmSystemType;
typedef HmPayload<HmSystemType> PayloadType; typedef HmPayload<HmSystemType> PayloadType;
typedef MiPayload<HmSystemType, HmRadio<>> MiPayloadType; typedef MiPayload<HmSystemType> MiPayloadType;
#ifdef ESP32 #ifdef ESP32
typedef CmtRadio<esp32_3wSpi> CmtRadioType; typedef CmtRadio<esp32_3wSpi> CmtRadioType;
#endif #endif

5
src/hm/hmInverter.h

@ -25,10 +25,6 @@
* automatically. Their result does not differ from original read values. * automatically. Their result does not differ from original read values.
*/ */
// forward declaration of class
template <class REC_TYP=float>
class Inverter;
// prototypes // prototypes
template<class T=float> template<class T=float>
@ -155,6 +151,7 @@ class Inverter {
uint16_t alarmLastId; // lastId which was received uint16_t alarmLastId; // lastId which was received
int8_t rssi; // RSSI int8_t rssi; // RSSI
Radio *radio; // pointer to associated radio class Radio *radio; // pointer to associated radio class
statistics_t radioStatistics; // information about transmitted, failed, ... packets
static uint32_t *timestamp; // system timestamp static uint32_t *timestamp; // system timestamp

30
src/hm/hmPayload.h

@ -43,10 +43,9 @@ class HmPayload {
public: public:
HmPayload() {} HmPayload() {}
void setup(IApp *app, HMSYSTEM *sys, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) { void setup(IApp *app, HMSYSTEM *sys, uint8_t maxRetransmits, uint32_t *timestamp) {
mApp = app; mApp = app;
mSys = sys; mSys = sys;
mStat = stat;
mMaxRetrans = maxRetransmits; mMaxRetrans = maxRetransmits;
mTimestamp = timestamp; mTimestamp = timestamp;
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
@ -115,11 +114,11 @@ class HmPayload {
if (mSerialDebug) if (mSerialDebug)
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
if (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId) { if (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId) {
mStat->rxFailNoAnser++; // got nothing iv->radioStatistics.rxFailNoAnser++; // got nothing
if (mSerialDebug) if (mSerialDebug)
DBGPRINTLN(F("enqueued cmd failed/timeout")); DBGPRINTLN(F("enqueued cmd failed/timeout"));
} else { } else {
mStat->rxFail++; // got fragments but not complete response iv->radioStatistics.rxFail++; // got fragments but not complete response
if (mSerialDebug) { if (mSerialDebug) {
DBGPRINT(F("no complete Payload received! (retransmits: ")); DBGPRINT(F("no complete Payload received! (retransmits: "));
DBGPRINT(String(mPayload[iv->id].retransmits)); DBGPRINT(String(mPayload[iv->id].retransmits));
@ -150,7 +149,7 @@ class HmPayload {
DBGPRINTLN(String(iv->powerLimit[0])); DBGPRINTLN(String(iv->powerLimit[0]));
} }
iv->powerLimitAck = false; iv->powerLimitAck = false;
iv->radio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false); iv->radio->sendControlPacket(iv, iv->devControlCmd, iv->powerLimit, false);
mPayload[iv->id].txCmd = iv->devControlCmd; mPayload[iv->id].txCmd = iv->devControlCmd;
//iv->clearCmdQueue(); //iv->clearCmdQueue();
//iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit //iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
@ -159,7 +158,7 @@ class HmPayload {
if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) { if((IV_HMS == iv->ivGen) || (IV_HMT == iv->ivGen)) {
record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug); record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);
if(((rec->ts + HMS_TIMEOUT_SEC) < *mTimestamp) && (mIvCmd56Cnt[iv->id] < 3)) { if(((rec->ts + HMS_TIMEOUT_SEC) < *mTimestamp) && (mIvCmd56Cnt[iv->id] < 3)) {
iv->radio->switchFrequency(iv->radioId.u64, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ); iv->radio->switchFrequency(iv, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ);
mIvCmd56Cnt[iv->id]++; mIvCmd56Cnt[iv->id]++;
return; return;
} else if(++mIvCmd56Cnt[iv->id] == 10) } else if(++mIvCmd56Cnt[iv->id] == 10)
@ -172,7 +171,7 @@ class HmPayload {
DBGPRINT(F("prepareDevInformCmd 0x")); DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(cmd); DBGHEXLN(cmd);
} }
iv->radio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); iv->radio->prepareDevInformCmd(iv, cmd, mPayload[iv->id].ts, iv->alarmLastId, false);
mPayload[iv->id].txCmd = cmd; mPayload[iv->id].txCmd = cmd;
} }
} }
@ -263,7 +262,7 @@ class HmPayload {
} else if(iv->devControlCmd == ActivePowerContr) { } else if(iv->devControlCmd == ActivePowerContr) {
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
DPRINTLN(DBG_INFO, F("retransmit power limit")); DPRINTLN(DBG_INFO, F("retransmit power limit"));
iv->radio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true); iv->radio->sendControlPacket(iv, iv->devControlCmd, iv->powerLimit, true);
} else { } else {
if(false == mPayload[iv->id].gotFragment) { if(false == mPayload[iv->id].gotFragment) {
DPRINT_IVID(DBG_WARN, iv->id); DPRINT_IVID(DBG_WARN, iv->id);
@ -274,7 +273,7 @@ class HmPayload {
DBGPRINTLN(F("nothing received: complete retransmit")); DBGPRINTLN(F("nothing received: complete retransmit"));
mPayload[iv->id].txCmd = iv->getQueuedCmd(); mPayload[iv->id].txCmd = iv->getQueuedCmd();
DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX));
iv->radio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); iv->radio->prepareDevInformCmd(iv, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
} }
} else { } else {
for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) {
@ -285,7 +284,7 @@ class HmPayload {
DBGPRINT(String(i + 1)); DBGPRINT(String(i + 1));
DBGPRINTLN(F(" missing: Request Retransmit")); DBGPRINTLN(F(" missing: Request Retransmit"));
} }
iv->radio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); iv->radio->sendCmdPacket(iv, TX_REQ_INFO, (SINGLE_FRAME + i), true);
break; // only request retransmit one frame per loop break; // only request retransmit one frame per loop
} }
yield(); yield();
@ -307,7 +306,7 @@ class HmPayload {
DBGPRINT(F("prepareDevInformCmd 0x")); DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(mPayload[iv->id].txCmd); DBGHEXLN(mPayload[iv->id].txCmd);
} }
iv->radio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true); iv->radio->prepareDevInformCmd(iv, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmLastId, true);
} }
} else { // payload complete } else { // payload complete
if (mSerialDebug) { if (mSerialDebug) {
@ -357,7 +356,7 @@ class HmPayload {
DPRINTLN(DBG_ERROR, F("record is NULL!")); DPRINTLN(DBG_ERROR, F("record is NULL!"));
} else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) { } else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) {
if (mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES)) if (mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES))
mStat->rxSuccess++; iv->radioStatistics.rxSuccess++;
rec->ts = mPayload[iv->id].ts; rec->ts = mPayload[iv->id].ts;
for (uint8_t i = 0; i < rec->length; i++) { for (uint8_t i = 0; i < rec->length; i++) {
@ -387,8 +386,8 @@ class HmPayload {
DBGPRINT(F("prepareDevInformCmd 0x")); DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(cmd); DBGHEXLN(cmd);
} }
mStat->rxSuccess++; iv->radioStatistics.rxSuccess++;
iv->radio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmLastId, false); iv->radio->prepareDevInformCmd(iv, cmd, mPayload[iv->id].ts, iv->alarmLastId, false);
mPayload[iv->id].txCmd = cmd; mPayload[iv->id].txCmd = cmd;
*/ */
mHighPrioIv = iv; mHighPrioIv = iv;
@ -400,7 +399,7 @@ class HmPayload {
DBGPRINT(String(rec->pyldLen)); DBGPRINT(String(rec->pyldLen));
DBGPRINTLN(F(" bytes")); DBGPRINTLN(F(" bytes"));
} }
mStat->rxFail++; iv->radioStatistics.rxFail++;
} }
iv->setQueuedCmdFinished(); iv->setQueuedCmdFinished();
@ -473,7 +472,6 @@ class HmPayload {
IApp *mApp; IApp *mApp;
HMSYSTEM *mSys; HMSYSTEM *mSys;
statistics_t *mStat;
uint8_t mMaxRetrans; uint8_t mMaxRetrans;
uint32_t *mTimestamp; uint32_t *mTimestamp;
invPayload_t mPayload[MAX_NUM_INVERTERS]; invPayload_t mPayload[MAX_NUM_INVERTERS];

32
src/hm/hmRadio.h

@ -54,10 +54,9 @@ class HmRadio : public Radio {
} }
~HmRadio() {} ~HmRadio() {}
void setup(statistics_t *stat, uint8_t ampPwr = RF24_PA_LOW, uint8_t irq = IRQ_PIN, uint8_t ce = CE_PIN, uint8_t cs = CS_PIN, uint8_t sclk = SCLK_PIN, uint8_t mosi = MOSI_PIN, uint8_t miso = MISO_PIN) { void setup(uint8_t ampPwr = RF24_PA_LOW, uint8_t irq = IRQ_PIN, uint8_t ce = CE_PIN, uint8_t cs = CS_PIN, uint8_t sclk = SCLK_PIN, uint8_t mosi = MOSI_PIN, uint8_t miso = MISO_PIN) {
DPRINTLN(DBG_VERBOSE, F("hmRadio.h:setup")); DPRINTLN(DBG_VERBOSE, F("hmRadio.h:setup"));
pinMode(irq, INPUT_PULLUP); pinMode(irq, INPUT_PULLUP);
mStat = stat;
uint32_t dtuSn = 0x87654321; uint32_t dtuSn = 0x87654321;
uint32_t chipID = 0; // will be filled with last 3 bytes of MAC uint32_t chipID = 0; // will be filled with last 3 bytes of MAC
@ -165,10 +164,10 @@ class HmRadio : public Radio {
mSerialDebug = true; mSerialDebug = true;
} }
void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) { void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) {
DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x")); DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x"));
DBGHEXLN(cmd); DBGHEXLN(cmd);
initPacket(invId, TX_REQ_DEVCONTROL, SINGLE_FRAME); initPacket(iv->radioId.u64, TX_REQ_DEVCONTROL, SINGLE_FRAME);
uint8_t cnt = 10; uint8_t cnt = 10;
if (isNoMI) { if (isNoMI) {
mTxBuf[cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor mTxBuf[cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor
@ -212,15 +211,15 @@ class HmRadio : public Radio {
} }
cnt++; cnt++;
} }
sendPacket(invId, cnt, isRetransmit, isNoMI); sendPacket(iv, cnt, isRetransmit, isNoMI);
} }
void prepareDevInformCmd(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg.
if(mSerialDebug) { if(mSerialDebug) {
DPRINT(DBG_DEBUG, F("prepareDevInformCmd 0x")); DPRINT(DBG_DEBUG, F("prepareDevInformCmd 0x"));
DPRINTLN(DBG_DEBUG,String(cmd, HEX)); DPRINTLN(DBG_DEBUG,String(cmd, HEX));
} }
initPacket(invId, reqfld, ALL_FRAMES); initPacket(iv->radioId.u64, reqfld, ALL_FRAMES);
mTxBuf[10] = cmd; // cid mTxBuf[10] = cmd; // cid
mTxBuf[11] = 0x00; mTxBuf[11] = 0x00;
CP_U32_LittleEndian(&mTxBuf[12], ts); CP_U32_LittleEndian(&mTxBuf[12], ts);
@ -228,12 +227,12 @@ class HmRadio : public Radio {
mTxBuf[18] = (alarmMesId >> 8) & 0xff; mTxBuf[18] = (alarmMesId >> 8) & 0xff;
mTxBuf[19] = (alarmMesId ) & 0xff; mTxBuf[19] = (alarmMesId ) & 0xff;
} }
sendPacket(invId, 24, isRetransmit); sendPacket(iv, 24, isRetransmit);
} }
void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) {
initPacket(invId, mid, pid); initPacket(iv->radioId.u64, mid, pid);
sendPacket(invId, 10, isRetransmit, appendCrc16); sendPacket(iv, 10, isRetransmit, appendCrc16);
} }
uint8_t getDataRate(void) { uint8_t getDataRate(void) {
@ -293,9 +292,9 @@ class HmRadio : public Radio {
mTxBuf[9] = pid; mTxBuf[9] = pid;
} }
void sendPacket(uint64_t invId, uint8_t len, bool isRetransmit, bool appendCrc16=true) { void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) {
//DPRINTLN(DBG_VERBOSE, F("hmRadio.h:sendPacket")); //DPRINTLN(DBG_VERBOSE, F("hmRadio.h:sendPacket"));
//DPRINTLN(DBG_VERBOSE, "sent packet: #" + String(mStat->txCnt)); //DPRINTLN(DBG_VERBOSE, "sent packet: #" + String(iv->radioStatistics.txCnt));
// append crc's // append crc's
if (appendCrc16 && (len > 10)) { if (appendCrc16 && (len > 10)) {
@ -323,13 +322,13 @@ class HmRadio : public Radio {
mNrf24.stopListening(); mNrf24.stopListening();
mNrf24.setChannel(mRfChLst[mTxChIdx]); mNrf24.setChannel(mRfChLst[mTxChIdx]);
mNrf24.openWritingPipe(reinterpret_cast<uint8_t*>(&invId)); 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
if(isRetransmit) if(isRetransmit)
mStat->retransmits++; iv->radioStatistics.retransmits++;
else else
mStat->txCnt++; iv->radioStatistics.txCnt++;
} }
volatile bool mIrqRcvd; volatile bool mIrqRcvd;
@ -342,7 +341,6 @@ class HmRadio : public Radio {
SPIClass* mSpi; SPIClass* mSpi;
RF24 mNrf24; RF24 mNrf24;
uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE]; uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE];
statistics_t *mStat;
}; };
#endif /*__HM_RADIO_H__*/ #endif /*__HM_RADIO_H__*/

42
src/hm/miPayload.h

@ -5,8 +5,6 @@
#ifndef __MI_PAYLOAD_H__ #ifndef __MI_PAYLOAD_H__
#define __MI_PAYLOAD_H__ #define __MI_PAYLOAD_H__
//#include "hmInverter.h"
#include "../utils/dbg.h" #include "../utils/dbg.h"
#include "../utils/crc.h" #include "../utils/crc.h"
#include "../config/config.h" #include "../config/config.h"
@ -35,16 +33,14 @@ typedef struct {
typedef std::function<void(uint8_t, Inverter<> *)> miPayloadListenerType; typedef std::function<void(uint8_t, Inverter<> *)> miPayloadListenerType;
template<class HMSYSTEM, class HMRADIO> template<class HMSYSTEM>
class MiPayload { class MiPayload {
public: public:
MiPayload() {} MiPayload() {}
void setup(IApp *app, HMSYSTEM *sys, HMRADIO *radio, statistics_t *stat, uint8_t maxRetransmits, uint32_t *timestamp) { void setup(IApp *app, HMSYSTEM *sys, uint8_t maxRetransmits, uint32_t *timestamp) {
mApp = app; mApp = app;
mSys = sys; mSys = sys;
mRadio = radio;
mStat = stat;
mMaxRetrans = maxRetransmits; mMaxRetrans = maxRetransmits;
mTimestamp = timestamp; mTimestamp = timestamp;
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) { for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i++) {
@ -89,11 +85,11 @@ class MiPayload {
if (mSerialDebug) if (mSerialDebug)
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
if (!mPayload[iv->id].gotFragment) { if (!mPayload[iv->id].gotFragment) {
mStat->rxFailNoAnser++; // got nothing iv->radioStatistics.rxFailNoAnser++; // got nothing
if (mSerialDebug) if (mSerialDebug)
DBGPRINTLN(F("enqueued cmd failed/timeout")); DBGPRINTLN(F("enqueued cmd failed/timeout"));
} else { } else {
mStat->rxFail++; // got "fragments" (part of the required messages) iv->radioStatistics.rxFail++; // got "fragments" (part of the required messages)
// but no complete set of responses // but no complete set of responses
if (mSerialDebug) { if (mSerialDebug) {
DBGPRINT(F("no complete Payload received! (retransmits: ")); DBGPRINT(F("no complete Payload received! (retransmits: "));
@ -127,7 +123,7 @@ class MiPayload {
DBGPRINTLN(String(iv->powerLimit[0])); DBGPRINTLN(String(iv->powerLimit[0]));
} }
iv->powerLimitAck = false; iv->powerLimitAck = false;
mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, false, false, iv->type == INV_TYPE_4CH); iv->radio->sendControlPacket(iv, iv->devControlCmd, iv->powerLimit, false, false, iv->type == INV_TYPE_4CH);
mPayload[iv->id].txCmd = iv->devControlCmd; mPayload[iv->id].txCmd = iv->devControlCmd;
mPayload[iv->id].limitrequested = true; mPayload[iv->id].limitrequested = true;
@ -153,7 +149,7 @@ class MiPayload {
DBGPRINT(F("prepareDevInformCmd 0x")); DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(cmd); DBGHEXLN(cmd);
} }
mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd2, false, false); iv->radio->sendCmdPacket(iv, cmd, cmd2, false, false);
mPayload[iv->id].txCmd = cmd; mPayload[iv->id].txCmd = cmd;
if (iv->type == INV_TYPE_1CH || iv->type == INV_TYPE_2CH) { if (iv->type == INV_TYPE_1CH || iv->type == INV_TYPE_2CH) {
@ -262,7 +258,7 @@ class MiPayload {
DPRINTLN(DBG_ERROR, F("record is NULL!")); DPRINTLN(DBG_ERROR, F("record is NULL!"));
} else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) { } else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) {
if (mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES)) if (mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES))
mStat->rxSuccess++; iv->radioStatistics.rxSuccess++;
rec->ts = mPayload[iv->id].ts; rec->ts = mPayload[iv->id].ts;
for (uint8_t i = 0; i < rec->length; i++) { for (uint8_t i = 0; i < rec->length; i++) {
@ -284,7 +280,7 @@ class MiPayload {
} }
} else { } else {
DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes")); DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes"));
mStat->rxFail++; iv->radioStatistics.rxFail++;
} }
iv->setQueuedCmdFinished(); iv->setQueuedCmdFinished();
@ -330,7 +326,7 @@ class MiPayload {
} else if(iv->devControlCmd == ActivePowerContr) { } else if(iv->devControlCmd == ActivePowerContr) {
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINTLN(F("retransmit power limit")); DBGPRINTLN(F("retransmit power limit"));
mRadio->sendControlPacket(iv->radioId.u64, iv->devControlCmd, iv->powerLimit, true, false); iv->radio->sendControlPacket(iv, iv->devControlCmd, iv->powerLimit, true, false);
} else { } else {
uint8_t cmd = mPayload[iv->id].txCmd; uint8_t cmd = mPayload[iv->id].txCmd;
if (mPayload[iv->id].retransmits < mMaxRetrans) { if (mPayload[iv->id].retransmits < mMaxRetrans) {
@ -343,10 +339,10 @@ class MiPayload {
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINTLN(F("retransmit on failed first request")); DBGPRINTLN(F("retransmit on failed first request"));
mPayload[iv->id].rxTmo = true; mPayload[iv->id].rxTmo = true;
mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd, true, false); iv->radio->sendCmdPacket(iv, cmd, cmd, true, false);
} else if ( cmd == 0x0f ) { } else if ( cmd == 0x0f ) {
//hard/firmware request //hard/firmware request
mRadio->sendCmdPacket(iv->radioId.u64, 0x0f, 0x00, true, false); iv->radio->sendCmdPacket(iv, 0x0f, 0x00, true, false);
mPayload[id].multi_parts = 0; mPayload[id].multi_parts = 0;
} else { } else {
bool change = false; bool change = false;
@ -384,7 +380,7 @@ class MiPayload {
DBGPRINT(F(" 0x")); DBGPRINT(F(" 0x"));
DBGHEXLN(cmd); DBGHEXLN(cmd);
mPayload[id].multi_parts = 0; mPayload[id].multi_parts = 0;
mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd, true, false); iv->radio->sendCmdPacket(iv, cmd, cmd, true, false);
yield(); yield();
} }
} else { } else {
@ -404,7 +400,7 @@ class MiPayload {
DBGPRINT(F("prepareDevInformCmd 0x")); DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(mPayload[iv->id].txCmd); DBGHEXLN(mPayload[iv->id].txCmd);
} }
mRadio->sendCmdPacket(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].txCmd, false, false); iv->radio->sendCmdPacket(iv, mPayload[iv->id].txCmd, mPayload[iv->id].txCmd, false, false);
} else { } else {
mPayload[iv->id].rxTmo = true; mPayload[iv->id].rxTmo = true;
} }
@ -420,9 +416,9 @@ class MiPayload {
DBGPRINT(F("prepareDevInformCmd 0x")); DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(cmd); DBGHEXLN(cmd);
} }
mStat->rxSuccess++; iv->radioStatistics.rxSuccess++;
//mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false); //iv->radio->prepareDevInformCmd(iv, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false);
mRadio->prepareDevInformCmd(iv->radioId.u64, iv->getType(), iv->radio->prepareDevInformCmd(iv, iv->getType(),
iv->getNextTxChanIndex(), cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false); iv->getNextTxChanIndex(), cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false);
mPayload[iv->id].txCmd = cmd; */ mPayload[iv->id].txCmd = cmd; */
if (mHighPrioIv == NULL) if (mHighPrioIv == NULL)
@ -600,7 +596,7 @@ class MiPayload {
iv->isProducing(); iv->isProducing();
iv->setQueuedCmdFinished(); iv->setQueuedCmdFinished();
mStat->rxSuccess++; iv->radioStatistics.rxSuccess++;
yield(); yield();
notify(RealTimeRunData_Debug, iv); notify(RealTimeRunData_Debug, iv);
} }
@ -756,7 +752,7 @@ const byteAssign_t InfoAssignment[] = {
mPayload[iv->id].complete = true; mPayload[iv->id].complete = true;
mPayload[iv->id].rxTmo = true; mPayload[iv->id].rxTmo = true;
mPayload[iv->id].requested= false; mPayload[iv->id].requested= false;
mStat->rxSuccess++; iv->radioStatistics.rxSuccess++;
} }
} }
@ -789,8 +785,6 @@ const byteAssign_t InfoAssignment[] = {
IApp *mApp; IApp *mApp;
HMSYSTEM *mSys; HMSYSTEM *mSys;
HMRADIO *mRadio;
statistics_t *mStat;
uint8_t mMaxRetrans; uint8_t mMaxRetrans;
uint32_t *mTimestamp; uint32_t *mTimestamp;
miPayload_t mPayload[MAX_NUM_INVERTERS]; miPayload_t mPayload[MAX_NUM_INVERTERS];

12
src/hm/radio.h

@ -11,13 +11,17 @@
#define ALL_FRAMES 0x80 #define ALL_FRAMES 0x80
#define SINGLE_FRAME 0x81 #define SINGLE_FRAME 0x81
// forward declaration of class
template <class REC_TYP=float>
class Inverter;
// abstract radio interface // abstract radio interface
class Radio { class Radio {
public: public:
virtual void sendControlPacket(uint64_t invId, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) = 0; virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) = 0;
virtual void prepareDevInformCmd(uint64_t invId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) = 0; virtual void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) = 0;
virtual void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) = 0; virtual void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) = 0;
virtual bool switchFrequency(uint64_t ivId, uint32_t fromkHz, uint32_t tokHz) { return true; } virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; }
}; };
#endif /*__RADIO_H__*/ #endif /*__RADIO_H__*/

38
src/hms/hmsRadio.h

@ -20,9 +20,8 @@ class CmtRadio : public Radio {
mCmtAvail = false; mCmtAvail = false;
} }
void setup(statistics_t *stat, uint8_t pinSclk, uint8_t pinSdio, uint8_t pinCsb, uint8_t pinFcsb, bool genDtuSn = true) { void setup(uint8_t pinSclk, uint8_t pinSdio, uint8_t pinCsb, uint8_t pinFcsb, bool genDtuSn = true) {
mCmt.setup(pinSclk, pinSdio, pinCsb, pinFcsb); mCmt.setup(pinSclk, pinSdio, pinCsb, pinFcsb);
mStat = stat;
reset(genDtuSn); reset(genDtuSn);
} }
@ -60,10 +59,10 @@ class CmtRadio : public Radio {
return mCmtAvail; return mCmtAvail;
} }
void sendControlPacket(uint64_t ivId, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) { void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit, bool isNoMI = true, bool is4chMI = false) {
DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x")); DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x"));
DBGHEXLN(cmd); DBGHEXLN(cmd);
initPacket(ivId, TX_REQ_DEVCONTROL, SINGLE_FRAME); initPacket(iv->radioId.u64, TX_REQ_DEVCONTROL, SINGLE_FRAME);
uint8_t cnt = 10; uint8_t cnt = 10;
mTxBuf[cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor mTxBuf[cnt++] = cmd; // cmd -> 0 on, 1 off, 2 restart, 11 active power, 12 reactive power, 13 power factor
@ -75,10 +74,10 @@ class CmtRadio : public Radio {
mTxBuf[cnt++] = ((data[1] ) ) & 0xff; // setting for persistens handling mTxBuf[cnt++] = ((data[1] ) ) & 0xff; // setting for persistens handling
} }
sendPacket(cnt, isRetransmit); sendPacket(iv, cnt, isRetransmit);
} }
bool switchFrequency(uint64_t ivId, uint32_t fromkHz, uint32_t tokHz) { bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) {
uint8_t fromCh = mCmt.freq2Chan(fromkHz); uint8_t fromCh = mCmt.freq2Chan(fromkHz);
uint8_t toCh = mCmt.freq2Chan(tokHz); uint8_t toCh = mCmt.freq2Chan(tokHz);
@ -86,28 +85,28 @@ class CmtRadio : public Radio {
return false; return false;
mCmt.switchChannel(fromCh); mCmt.switchChannel(fromCh);
sendSwitchChCmd(ivId, toCh); sendSwitchChCmd(iv, toCh);
mCmt.switchChannel(toCh); mCmt.switchChannel(toCh);
return true; return true;
} }
void prepareDevInformCmd(uint64_t ivId, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg. void prepareDevInformCmd(Inverter<> *iv, uint8_t cmd, uint32_t ts, uint16_t alarmMesId, bool isRetransmit, uint8_t reqfld=TX_REQ_INFO) { // might not be necessary to add additional arg.
initPacket(ivId, reqfld, ALL_FRAMES); initPacket(iv->radioId.u64, reqfld, ALL_FRAMES);
mTxBuf[10] = cmd; mTxBuf[10] = cmd;
CP_U32_LittleEndian(&mTxBuf[12], ts); CP_U32_LittleEndian(&mTxBuf[12], ts);
if (cmd == AlarmData ) { //cmd == RealTimeRunData_Debug || if (cmd == AlarmData ) { //cmd == RealTimeRunData_Debug ||
mTxBuf[18] = (alarmMesId >> 8) & 0xff; mTxBuf[18] = (alarmMesId >> 8) & 0xff;
mTxBuf[19] = (alarmMesId ) & 0xff; mTxBuf[19] = (alarmMesId ) & 0xff;
} }
sendPacket(24, isRetransmit); sendPacket(iv, 24, isRetransmit);
} }
void sendCmdPacket(uint64_t ivId, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) { void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) {
initPacket(ivId, mid, pid); initPacket(iv->radioId.u64, mid, pid);
sendPacket(10, isRetransmit); sendPacket(iv, 10, isRetransmit);
} }
void sendPacket(uint8_t len, bool isRetransmit) { void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit) {
if (len > 14) { if (len > 14) {
uint16_t crc = ah::crc16(&mTxBuf[10], len - 10); uint16_t crc = ah::crc16(&mTxBuf[10], len - 10);
mTxBuf[len++] = (crc >> 8) & 0xff; mTxBuf[len++] = (crc >> 8) & 0xff;
@ -132,9 +131,9 @@ class CmtRadio : public Radio {
} }
if(isRetransmit) if(isRetransmit)
mStat->retransmits++; iv->radioStatistics.retransmits++;
else else
mStat->txCnt++; iv->radioStatistics.txCnt++;
} }
std::queue<packet_t> mBufCtrl; std::queue<packet_t> mBufCtrl;
@ -156,7 +155,7 @@ class CmtRadio : public Radio {
mRqstGetRx = false; mRqstGetRx = false;
} }
inline void sendSwitchChCmd(uint64_t ivId, uint8_t ch) { inline void sendSwitchChCmd(Inverter<> *iv, uint8_t ch) {
/** ch: /** ch:
* 0x00: 860.00 MHz * 0x00: 860.00 MHz
* 0x01: 860.25 MHz * 0x01: 860.25 MHz
@ -166,12 +165,12 @@ class CmtRadio : public Radio {
* ... * ...
* 0x28: 870.00 MHz * 0x28: 870.00 MHz
* */ * */
initPacket(ivId, 0x56, 0x02); initPacket(iv->radioId.u64, 0x56, 0x02);
mTxBuf[10] = 0x15; mTxBuf[10] = 0x15;
mTxBuf[11] = 0x21; mTxBuf[11] = 0x21;
mTxBuf[12] = ch; mTxBuf[12] = ch;
mTxBuf[13] = 0x14; mTxBuf[13] = 0x14;
sendPacket(14, false); sendPacket(iv, 14, false);
mRqstGetRx = true; mRqstGetRx = true;
} }
@ -210,7 +209,6 @@ class CmtRadio : public Radio {
bool mIrqRcvd; bool mIrqRcvd;
bool mRqstGetRx; bool mRqstGetRx;
bool mCmtAvail; bool mCmtAvail;
statistics_t *mStat;
}; };
#endif /*__HMS_RADIO_H__*/ #endif /*__HMS_RADIO_H__*/

Loading…
Cancel
Save