Browse Source

non blocking - first review

- discord 0.8.5902
- stay longer on expected rx channel to wait for first frame 
- stick to looping over 5 channels for MI (after first frame or timeout)
pull/1371/head
rejoe2 1 year ago
committed by GitHub
parent
commit
ac0c93cb40
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 21
      src/app.cpp
  2. 4
      src/app.h
  3. 4
      src/hm/CommQueue.h
  4. 27
      src/hm/Communication.h
  5. 7
      src/hm/hmDefines.h
  6. 1
      src/hm/hmInverter.h
  7. 36
      src/hm/hmRadio.h
  8. 16
      src/hm/hmSystem.h

21
src/app.cpp

@ -106,7 +106,7 @@ void app::setup() {
#endif
// Plugins
#if defined(PLUGIN_DISPLAY)
if (mConfig->plugin.display.type != 0)
if (DISP_TYPE_T0_NONE != mConfig->plugin.display.type)
#if defined(ESP32)
mDisplay.setup(this, &mConfig->plugin.display, &mSys, &mNrfRadio, &mCmtRadio, &mTimestamp);
#else
@ -184,7 +184,7 @@ void app::regularTickers(void) {
everySec(std::bind(&WebType::tickSecond, &mWeb), "webSc");
// Plugins
#if defined(PLUGIN_DISPLAY)
if (mConfig->plugin.display.type != 0)
if (DISP_TYPE_T0_NONE != mConfig->plugin.display.type)
everySec(std::bind(&DisplayType::tickerSecond, &mDisplay), "disp");
#endif
every(std::bind(&PubSerialType::tick, &mPubSerial), 5, "uart");
@ -350,6 +350,14 @@ void app::tickSunrise(void) {
#endif
}
//-----------------------------------------------------------------------------
void app::notAvailChanged(void) {
#if defined(ENABLE_MQTT)
if (mMqttEnabled)
mMqtt.notAvailChanged(mAllIvNotAvail);
#endif
}
//-----------------------------------------------------------------------------
void app::tickZeroValues(void) {
zeroIvValues(!CHECK_AVAIL, SKIP_YIELD_DAY);
@ -401,6 +409,7 @@ void app::tickMidnight(void) {
//-----------------------------------------------------------------------------
void app::tickSend(void) {
bool notAvail = true;
uint8_t fill = mCommunication.getFillState();
uint8_t max = mCommunication.getMaxFill();
if((max-MAX_NUM_INVERTERS) <= fill) {
@ -426,6 +435,9 @@ void app::tickSend(void) {
if(!iv->radio->isChipConnected())
continue;
if(InverterStatus::OFF != iv->status)
notAvail = false;
iv->tickSend([this, iv](uint8_t cmd, bool isDevControl) {
if(isDevControl)
mCommunication.addImportant(iv, cmd);
@ -435,6 +447,10 @@ void app::tickSend(void) {
}
}
if(mAllIvNotAvail != notAvail)
once(std::bind(&app::notAvailChanged, this), 1, "avail");
mAllIvNotAvail = notAvail;
updateLed();
}
@ -533,6 +549,7 @@ void app::resetSystem(void) {
#endif
mSendFirst = true;
mAllIvNotAvail = true;
mSunrise = 0;
mSunset = 0;

4
src/app.h

@ -320,7 +320,7 @@ class app : public IApp, public ah::Scheduler {
#endif /*ENABLE_MQTT*/
#endif
#if defined(PLUGIN_DISPLAY)
if(mConfig->plugin.display.type != 0)
if(DISP_TYPE_T0_NONE != mConfig->plugin.display.type)
mDisplay.payloadEventListener(cmd);
#endif
updateLed();
@ -367,6 +367,7 @@ class app : public IApp, public ah::Scheduler {
void tickMinute(void);
void tickZeroValues(void);
void tickMidnight(void);
void notAvailChanged(void);
HmSystemType mSys;
HmRadio<> mNrfRadio;
@ -403,6 +404,7 @@ class app : public IApp, public ah::Scheduler {
uint8_t mSendLastIvId;
bool mSendFirst;
bool mAllIvNotAvail;
bool mNetworkConnected;

4
src/hm/CommQueue.h

@ -12,8 +12,8 @@
#include "../utils/dbg.h"
#define DEFAULT_ATTEMPS 5
#define MORE_ATTEMPS_ALARMDATA 15
#define MORE_ATTEMPS_GRIDONPROFILEPARA 15
#define MORE_ATTEMPS_ALARMDATA 8
#define MORE_ATTEMPS_GRIDONPROFILEPARA 5
template <uint8_t N=100>
class CommQueue {

27
src/hm/Communication.h

@ -89,14 +89,14 @@ class Communication : public CommQueue<> {
q->iv->mCmd = q->cmd;
q->iv->mIsSingleframeReq = false;
mFramesExpected = getFramesExpected(q); // function to get expected frame count.
mTimeout = DURATION_TXFRAME + mFramesExpected*DURATION_ONEFRAME + DURATION_RESERVE;
mTimeout = DURATION_TXFRAME + mFramesExpected*DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType];
mState = States::START;
break;
case States::START:
setTs(mTimestamp);
if((IV_HMS == q->iv->ivGen) || (IV_HMT == q->iv->ivGen)) {
if(q->iv->ivRadioType == INV_RADIO_TYPE_CMT) {
// frequency was changed during runtime
if(q->iv->curCmtFreq != q->iv->config->frequency) {
if(q->iv->radio->switchFrequencyCh(q->iv, q->iv->curCmtFreq, q->iv->config->frequency))
@ -136,7 +136,7 @@ class Communication : public CommQueue<> {
DBGPRINTLN(F("ms"));
}
if(!q->iv->mGotFragment) {
if((IV_HMS == q->iv->ivGen) || (IV_HMT == q->iv->ivGen)) {
if(q->iv->ivRadioType == INV_RADIO_TYPE_CMT) {
q->iv->radio->switchFrequency(q->iv, HOY_BOOT_FREQ_KHZ, (q->iv->config->frequency*FREQ_STEP_KHZ + HOY_BASE_FREQ_KHZ));
mWaitTime.startTimeMonitor(1000);
} else {
@ -284,7 +284,7 @@ class Communication : public CommQueue<> {
DBGPRINT(String(p->millis));
DBGPRINT(F("ms | "));
DBGPRINT(String(p->len));
if((IV_HM == q->iv->ivGen) || (IV_MI == q->iv->ivGen)) {
if(q->iv->ivRadioType == INV_RADIO_TYPE_NRF) {
DBGPRINT(F(" CH"));
if(3 == p->ch)
DBGPRINT(F("0"));
@ -316,13 +316,8 @@ class Communication : public CommQueue<> {
if(q->iv->ivGen != IV_MI) {
if (q->cmd == RealTimeRunData_Debug) {
switch (q->iv->type) { // breaks are intentionally missing!
case INV_TYPE_1CH: return 2;
case INV_TYPE_2CH: return 3;
case INV_TYPE_4CH: return 4;
case INV_TYPE_6CH: return 7;
default: return 7;
}
uint8_t framecnt[4] = {2, 3, 4, 7};
return framecnt[q->iv->type];
}
switch (q->cmd) {
@ -350,8 +345,8 @@ class Communication : public CommQueue<> {
} else { //MI
switch (q->cmd) {
case 0x09:
case 0x11:
case MI_REQ_CH1:
case MI_REQ_CH2:
return 2;
case 0x0f: return 3;
default: return 1;
@ -582,7 +577,7 @@ class Communication : public CommQueue<> {
q->iv->radio->setExpectedFrames(mFramesExpected);
q->iv->radio->sendCmdPacket(q->iv, TX_REQ_INFO, (SINGLE_FRAME + i), true);
q->iv->radioStatistics.retransmits++;
q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + DURATION_RESERVE);
q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]);
mState = States::WAIT;
}
@ -827,7 +822,7 @@ class Communication : public CommQueue<> {
q->iv->radio->setExpectedFrames(mFramesExpected);
q->iv->radio->sendCmdPacket(q->iv, cmd, 0x00, true);
q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + DURATION_RESERVE);
q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]);
q->iv->miMultiParts = 0;
q->iv->mGotFragment = 0;
mIsRetransmit = true;
@ -847,7 +842,7 @@ class Communication : public CommQueue<> {
q->iv->radio->sendCmdPacket(q->iv, q->cmd, 0x00, true);
q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + DURATION_RESERVE);
q->iv->radio->mRadioWaitTime.startTimeMonitor(DURATION_TXFRAME + DURATION_ONEFRAME + duration_reserve[q->iv->ivRadioType]);
mIsRetransmit = false;
}

7
src/hm/hmDefines.h

@ -76,6 +76,7 @@ enum {CMD_CALC = 0xffff};
enum {CH0 = 0, CH1, CH2, CH3, CH4, CH5, CH6};
enum {INV_TYPE_1CH = 0, INV_TYPE_2CH, INV_TYPE_4CH, INV_TYPE_6CH};
enum {INV_RADIO_TYPE_NRF = 0, INV_RADIO_TYPE_CMT};
#define WORK_FREQ_KHZ 865000 // desired work frequency between DTU and
// inverter in kHz
@ -87,11 +88,11 @@ enum {INV_TYPE_1CH = 0, INV_TYPE_2CH, INV_TYPE_4CH, INV_TYPE_6CH};
#define FREQ_WARN_MAX_KHZ 870000 // for EU 863 - 870 MHz is allowed
#define DURATION_ONEFRAME 50 // timeout parameter for each expected frame (ms)
#define DURATION_RESERVE 90 // timeout parameter to still wait after last expected frame (ms)
#define DURATION_TXFRAME 60 // timeout parameter for first transmission and first expected frame (time to first channel switch from tx start!) (ms)
//#define DURATION_RESERVE {90,120} // timeout parameter to still wait after last expected frame (ms)
#define DURATION_TXFRAME 85 // timeout parameter for first transmission and first expected frame (time to first channel switch from tx start!) (ms)
#define DURATION_LISTEN_MIN 5 // time to stay at least on a listening channel (ms)
#define DURATION_PAUSE_LASTFR 45 // how long to pause after last frame (ms)
const uint8_t duration_reserve[2] = {115,115};
typedef struct {
uint8_t fieldId; // field id

1
src/hm/hmInverter.h

@ -114,6 +114,7 @@ template <class REC_TYP>
class Inverter {
public:
uint8_t ivGen; // generation of inverter (HM / MI)
uint8_t ivRadioType; // refers to used radio (nRF24 / CMT)
cfgIv_t *config; // stored settings
uint8_t id; // unique id
uint8_t type; // integer which refers to inverter type

36
src/hm/hmRadio.h

@ -125,11 +125,16 @@ class HmRadio : public Radio {
// otherwise switch to next RX channel
mTimeslotStart = millis();
if(!mNRFloopChannels && (mTimeslotStart - mLastIrqTime > (DURATION_TXFRAME+DURATION_ONEFRAME)))
mNRFloopChannels = true;
rxPendular = !rxPendular;
//innerLoopTimeout = (rxPendular ? 1 : 2)*DURATION_LISTEN_MIN;
innerLoopTimeout = DURATION_LISTEN_MIN;
tempRxChIdx = (mRxChIdx + rxPendular*chOffset2) % RF_CHANNELS;
tempRxChIdx = mNRFloopChannels ?
(tempRxChIdx + 4) % RF_CHANNELS :
(mRxChIdx + rxPendular*4) % RF_CHANNELS;
mNrf24->setChannel(mRfChLst[tempRxChIdx]);
isRxInit = false;
@ -140,6 +145,7 @@ class HmRadio : public Radio {
mNrf24->whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH
mIrqRcvd = false;
mLastIrqTime = millis();
if(tx_ok || tx_fail) { // tx related interrupt, basically we should start listening
mNrf24->flush_tx(); // empty TX FIFO
@ -154,13 +160,13 @@ class HmRadio : public Radio {
mLastIv->mAckCount++;
// start listening
mRxChIdx = (mTxChIdx + chOffset) % RF_CHANNELS;
mRxChIdx = (mTxChIdx + 2 ) % RF_CHANNELS;
mNrf24->setChannel(mRfChLst[mRxChIdx]);
mNrf24->startListening();
mTimeslotStart = millis();
tempRxChIdx = mRxChIdx;
chOffset2 = mLastIv->ivGen == IV_HM ? 4 : (mLastIv->mCmd == MI_REQ_CH1 || mLastIv->mCmd == MI_REQ_CH2) ? 1 :4; // reversed channel order for everything apart from 1/2ch MI Data requests
rxPendular = false;
mNRFloopChannels = mLastIv->ivGen == IV_MI;
innerLoopTimeout = DURATION_TXFRAME;
}
@ -172,17 +178,18 @@ class HmRadio : public Radio {
mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first end his transmissions
// add stop listening?
} else {
//rxPendular = true; // stay longer on the next rx channel
if (isRxInit) {
isRxInit = false;
tempRxChIdx = (mRxChIdx + chOffset2) % RF_CHANNELS;
mNrf24->setChannel(mRfChLst[tempRxChIdx]);
} else {
mRxChIdx = tempRxChIdx;
}
innerLoopTimeout = DURATION_LISTEN_MIN;
mTimeslotStart = millis();
if (!mNRFloopChannels) {
//rxPendular = true; // stay longer on the next rx channel
if (isRxInit) {
isRxInit = false;
tempRxChIdx = (mRxChIdx + 4) % RF_CHANNELS;
mNrf24->setChannel(mRfChLst[tempRxChIdx]);
} else
mRxChIdx = tempRxChIdx;
}
}
return;
}
@ -396,14 +403,13 @@ class HmRadio : public Radio {
bool mGotLastMsg = false;
uint32_t mMillis;
bool tx_ok, tx_fail, rx_ready = false;
uint8_t chOffset = 2;
uint8_t chOffset2 = 4;
unsigned long mTimeslotStart = 0;
unsigned long mLastIrqTime = 0;
bool mNRFloopChannels = false;
bool mNRFisInRX = false;
bool isRxInit = true;
bool rxPendular = false;
uint32_t innerLoopTimeout = DURATION_LISTEN_MIN;
//uint32_t outerLoopTimeout = 400;
std::unique_ptr<SPIClass> mSpi;
std::unique_ptr<RF24> mNrf24;

16
src/hm/hmSystem.h

@ -51,15 +51,21 @@ class HmSystem {
}
if(iv->config->serial.b[5] == 0x11) {
if((iv->config->serial.b[4] & 0x0f) == 0x04)
if((iv->config->serial.b[4] & 0x0f) == 0x04) {
iv->ivGen = IV_HMS;
else
iv->ivRadioType = INV_RADIO_TYPE_CMT;
} else {
iv->ivGen = IV_HM;
iv->ivRadioType = INV_RADIO_TYPE_NRF;
}
}
else if((iv->config->serial.b[4] & 0x03) == 0x02) // MI 3rd Gen -> same as HM
else if((iv->config->serial.b[4] & 0x03) == 0x02) { // MI 3rd Gen -> same as HM
iv->ivGen = IV_HM;
else // MI 2nd Gen
iv->ivRadioType = INV_RADIO_TYPE_NRF;
} else { // MI 2nd Gen
iv->ivGen = IV_MI;
iv->ivRadioType = INV_RADIO_TYPE_NRF;
}
} else if(iv->config->serial.b[5] == 0x13) {
iv->ivGen = IV_HMT;
iv->type = INV_TYPE_6CH;
@ -87,7 +93,7 @@ class HmSystem {
DBGPRINTLN(String(iv->config->serial.u64, HEX));
if((iv->config->serial.b[5] == 0x10) && ((iv->config->serial.b[4] & 0x03) == 0x01))
DPRINTLN(DBG_WARN, F("MI Inverter are not fully supported now!!!"));
DPRINTLN(DBG_WARN, F("MI Inverter, has some restrictions!"));
cb(iv);
}

Loading…
Cancel
Save