mirror of
https://github.com/lumapu/ahoy.git
synced 2025-06-06 12:41:37 +02:00
0.8.61 - 2024-01-21
* add favicon to header * improved NRF communication
This commit is contained in:
parent
94f5a2ad11
commit
6cbcbbafc5
10 changed files with 353 additions and 320 deletions
|
@ -1,5 +1,9 @@
|
||||||
# Development Changes
|
# Development Changes
|
||||||
|
|
||||||
|
## 0.8.61 - 2024-01-21
|
||||||
|
* add favicon to header
|
||||||
|
* improved NRF communication
|
||||||
|
|
||||||
## 0.8.60 - 2024-01-20
|
## 0.8.60 - 2024-01-20
|
||||||
* merge PR: non blocking nRF loop #1371
|
* merge PR: non blocking nRF loop #1371
|
||||||
* merge PR: fixed millis in serial log #1373
|
* merge PR: fixed millis in serial log #1373
|
||||||
|
|
25
src/app.cpp
25
src/app.cpp
|
@ -143,19 +143,22 @@ void app::loop(void) {
|
||||||
esp_task_wdt_reset();
|
esp_task_wdt_reset();
|
||||||
|
|
||||||
if(mConfig->nrf.enabled)
|
if(mConfig->nrf.enabled)
|
||||||
mNrfRadio.loop();
|
mNrfActive = mNrfRadio.loop();
|
||||||
#if defined(ESP32)
|
|
||||||
if(mConfig->cmt.enabled)
|
|
||||||
mCmtRadio.loop();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ah::Scheduler::loop();
|
if(!mNrfActive) {
|
||||||
mCommunication.loop();
|
#if defined(ESP32)
|
||||||
|
if(mConfig->cmt.enabled)
|
||||||
|
mNrfActive = mCmtRadio.loop();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_MQTT)
|
ah::Scheduler::loop();
|
||||||
if (mMqttEnabled && mNetworkConnected)
|
mCommunication.loop();
|
||||||
mMqtt.loop();
|
|
||||||
#endif
|
#if defined(ENABLE_MQTT)
|
||||||
|
if (mMqttEnabled && mNetworkConnected)
|
||||||
|
mMqtt.loop();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -405,6 +405,7 @@ class app : public IApp, public ah::Scheduler {
|
||||||
uint8_t mSendLastIvId;
|
uint8_t mSendLastIvId;
|
||||||
bool mSendFirst;
|
bool mSendFirst;
|
||||||
bool mAllIvNotAvail;
|
bool mAllIvNotAvail;
|
||||||
|
bool mNrfActive = false;
|
||||||
|
|
||||||
bool mNetworkConnected;
|
bool mNetworkConnected;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 8
|
#define VERSION_MINOR 8
|
||||||
#define VERSION_PATCH 60
|
#define VERSION_PATCH 61
|
||||||
|
|
||||||
//-------------------------------------
|
//-------------------------------------
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -61,221 +61,220 @@ class Communication : public CommQueue<> {
|
||||||
mLastEmptyQueueMillis = millis();
|
mLastEmptyQueueMillis = millis();
|
||||||
mPrintSequenceDuration = true;
|
mPrintSequenceDuration = true;
|
||||||
|
|
||||||
/*if(mDebugState != mState) {
|
innerLoop(q);
|
||||||
DPRINT(DBG_INFO, F("State: "));
|
|
||||||
DBGHEXLN((uint8_t)(mState));
|
|
||||||
mDebugState = mState;
|
|
||||||
}*/
|
|
||||||
switch(mState) {
|
|
||||||
case States::RESET:
|
|
||||||
if (!mWaitTime.isTimeout())
|
|
||||||
return;
|
|
||||||
|
|
||||||
mMaxFrameId = 0;
|
|
||||||
for(uint8_t i = 0; i < MAX_PAYLOAD_ENTRIES; i++) {
|
|
||||||
mLocalBuf[i].len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(*mSerialDebug)
|
|
||||||
mHeu.printStatus(q->iv);
|
|
||||||
mHeu.getTxCh(q->iv);
|
|
||||||
q->iv->mGotFragment = false;
|
|
||||||
q->iv->mGotLastMsg = false;
|
|
||||||
q->iv->curFrmCnt = 0;
|
|
||||||
mIsRetransmit = false;
|
|
||||||
if(NULL == q->iv->radio)
|
|
||||||
cmdDone(false); // can't communicate while radio is not defined!
|
|
||||||
mFirstTry = q->iv->isAvailable();
|
|
||||||
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[q->iv->ivRadioType];
|
|
||||||
|
|
||||||
mState = States::START;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case States::START:
|
|
||||||
setTs(mTimestamp);
|
|
||||||
if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) {
|
|
||||||
// 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))
|
|
||||||
q->iv->curCmtFreq = q->iv->config->frequency;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(q->isDevControl) {
|
|
||||||
if(ActivePowerContr == q->cmd)
|
|
||||||
q->iv->powerLimitAck = false;
|
|
||||||
q->iv->radio->sendControlPacket(q->iv, q->cmd, q->iv->powerLimit, false);
|
|
||||||
} else
|
|
||||||
q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false);
|
|
||||||
|
|
||||||
q->iv->radioStatistics.txCnt++;
|
|
||||||
q->iv->radio->mRadioWaitTime.startTimeMonitor(mTimeout);
|
|
||||||
|
|
||||||
mIsRetransmit = false;
|
|
||||||
setAttempt();
|
|
||||||
if((q->cmd == AlarmData) || (q->cmd == GridOnProFilePara))
|
|
||||||
incrAttempt(q->cmd == AlarmData? MORE_ATTEMPS_ALARMDATA : MORE_ATTEMPS_GRIDONPROFILEPARA);
|
|
||||||
mState = States::WAIT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case States::WAIT:
|
|
||||||
if (!q->iv->radio->mRadioWaitTime.isTimeout())
|
|
||||||
return;
|
|
||||||
mState = States::CHECK_FRAMES;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case States::CHECK_FRAMES: {
|
|
||||||
if((q->iv->radio->mBufCtrl.empty() && !mIsRetransmit) || (0 == q->attempts)) { // radio buffer empty or no more answers
|
|
||||||
if(*mSerialDebug) {
|
|
||||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
|
||||||
DBGPRINT(F("request timeout: "));
|
|
||||||
DBGPRINT(String(q->iv->radio->mRadioWaitTime.getRunTime()));
|
|
||||||
DBGPRINTLN(F("ms"));
|
|
||||||
}
|
|
||||||
if(!q->iv->mGotFragment) {
|
|
||||||
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 {
|
|
||||||
if(IV_MI == q->iv->ivGen)
|
|
||||||
q->iv->mIvTxCnt++;
|
|
||||||
if(mFirstTry) {
|
|
||||||
mFirstTry = false;
|
|
||||||
setAttempt();
|
|
||||||
mHeu.evalTxChQuality(q->iv, false, 0, 0);
|
|
||||||
//q->iv->radioStatistics.rxFailNoAnser++;
|
|
||||||
q->iv->radioStatistics.retransmits++;
|
|
||||||
q->iv->radio->mRadioWaitTime.stopTimeMonitor();
|
|
||||||
mState = States::START;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closeRequest(q, false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mFirstTry = false; // for correct reset
|
|
||||||
if((IV_MI != q->iv->ivGen) || (0 == q->attempts))
|
|
||||||
mIsRetransmit = false;
|
|
||||||
|
|
||||||
while(!q->iv->radio->mBufCtrl.empty()) {
|
|
||||||
packet_t *p = &q->iv->radio->mBufCtrl.front();
|
|
||||||
|
|
||||||
if(validateIvSerial(&p->packet[1], q->iv)) {
|
|
||||||
printRxInfo(q, p);
|
|
||||||
q->iv->radioStatistics.frmCnt++;
|
|
||||||
q->iv->mDtuRxCnt++;
|
|
||||||
|
|
||||||
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
|
|
||||||
if(parseFrame(p))
|
|
||||||
q->iv->curFrmCnt++;
|
|
||||||
} else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command
|
|
||||||
if(parseDevCtrl(p, q))
|
|
||||||
closeRequest(q, true);
|
|
||||||
else
|
|
||||||
closeRequest(q, false);
|
|
||||||
q->iv->radio->mBufCtrl.pop();
|
|
||||||
return; // don't wait for empty buffer
|
|
||||||
} else if(IV_MI == q->iv->ivGen) {
|
|
||||||
if(parseMiFrame(p, q))
|
|
||||||
q->iv->curFrmCnt++;
|
|
||||||
}
|
|
||||||
} //else -> serial does not match
|
|
||||||
|
|
||||||
q->iv->radio->mBufCtrl.pop();
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(q->iv->ivGen != IV_MI) {
|
|
||||||
mState = States::CHECK_PACKAGE;
|
|
||||||
} else {
|
|
||||||
bool fastNext = true;
|
|
||||||
if(q->iv->miMultiParts < 6) {
|
|
||||||
mState = States::WAIT;
|
|
||||||
if((q->iv->radio->mRadioWaitTime.isTimeout() && mIsRetransmit) || !mIsRetransmit) {
|
|
||||||
miRepeatRequest(q);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mHeu.evalTxChQuality(q->iv, true, (q->attemptsMax - 1 - q->attempts), q->iv->curFrmCnt);
|
|
||||||
if(((q->cmd == 0x39) && (q->iv->type == INV_TYPE_4CH))
|
|
||||||
|| ((q->cmd == MI_REQ_CH2) && (q->iv->type == INV_TYPE_2CH))
|
|
||||||
|| ((q->cmd == MI_REQ_CH1) && (q->iv->type == INV_TYPE_1CH))) {
|
|
||||||
miComplete(q->iv);
|
|
||||||
fastNext = false;
|
|
||||||
}
|
|
||||||
if(fastNext)
|
|
||||||
miNextRequest(q->iv->type == INV_TYPE_4CH ? MI_REQ_4CH : MI_REQ_CH1, q);
|
|
||||||
else
|
|
||||||
closeRequest(q, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case States::CHECK_PACKAGE:
|
|
||||||
uint8_t framnr = 0;
|
|
||||||
if(0 == mMaxFrameId) {
|
|
||||||
uint8_t i = 0;
|
|
||||||
while(i < MAX_PAYLOAD_ENTRIES) {
|
|
||||||
if(mLocalBuf[i].len == 0) {
|
|
||||||
framnr = i+1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!framnr) {
|
|
||||||
for(uint8_t i = 0; i < mMaxFrameId; i++) {
|
|
||||||
if(mLocalBuf[i].len == 0) {
|
|
||||||
framnr = i+1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(framnr) {
|
|
||||||
if(0 == q->attempts) {
|
|
||||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
|
||||||
DBGPRINT(F("no attempts left"));
|
|
||||||
closeRequest(q, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setAttempt();
|
|
||||||
|
|
||||||
if(*mSerialDebug) {
|
|
||||||
DPRINT_IVID(DBG_WARN, q->iv->id);
|
|
||||||
DBGPRINT(F("frame "));
|
|
||||||
DBGPRINT(String(framnr));
|
|
||||||
DBGPRINT(F(" missing: request retransmit ("));
|
|
||||||
DBGPRINT(String(q->attempts));
|
|
||||||
DBGPRINTLN(F(" attempts left)"));
|
|
||||||
}
|
|
||||||
if (!mIsRetransmit)
|
|
||||||
q->iv->mIsSingleframeReq = true;
|
|
||||||
sendRetransmit(q, (framnr-1));
|
|
||||||
mIsRetransmit = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
compilePayload(q);
|
|
||||||
|
|
||||||
if((NULL != mCbPayload) && (GridOnProFilePara != q->cmd) && (GetLossRate != q->cmd))
|
|
||||||
(mCbPayload)(q->cmd, q->iv);
|
|
||||||
|
|
||||||
closeRequest(q, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
inline void innerLoop(const queue_s *q) {
|
||||||
|
switch(mState) {
|
||||||
|
case States::RESET:
|
||||||
|
if (!mWaitTime.isTimeout())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mMaxFrameId = 0;
|
||||||
|
for(uint8_t i = 0; i < MAX_PAYLOAD_ENTRIES; i++) {
|
||||||
|
mLocalBuf[i].len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*mSerialDebug)
|
||||||
|
mHeu.printStatus(q->iv);
|
||||||
|
mHeu.getTxCh(q->iv);
|
||||||
|
q->iv->mGotFragment = false;
|
||||||
|
q->iv->mGotLastMsg = false;
|
||||||
|
q->iv->curFrmCnt = 0;
|
||||||
|
mIsRetransmit = false;
|
||||||
|
if(NULL == q->iv->radio)
|
||||||
|
cmdDone(false); // can't communicate while radio is not defined!
|
||||||
|
mFirstTry = q->iv->isAvailable();
|
||||||
|
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[q->iv->ivRadioType];
|
||||||
|
|
||||||
|
mState = States::START;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case States::START:
|
||||||
|
setTs(mTimestamp);
|
||||||
|
if(INV_RADIO_TYPE_CMT == q->iv->ivRadioType) {
|
||||||
|
// 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))
|
||||||
|
q->iv->curCmtFreq = q->iv->config->frequency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(q->isDevControl) {
|
||||||
|
if(ActivePowerContr == q->cmd)
|
||||||
|
q->iv->powerLimitAck = false;
|
||||||
|
q->iv->radio->sendControlPacket(q->iv, q->cmd, q->iv->powerLimit, false);
|
||||||
|
} else
|
||||||
|
q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false);
|
||||||
|
|
||||||
|
q->iv->radioStatistics.txCnt++;
|
||||||
|
q->iv->radio->mRadioWaitTime.startTimeMonitor(mTimeout);
|
||||||
|
|
||||||
|
mIsRetransmit = false;
|
||||||
|
setAttempt();
|
||||||
|
if((q->cmd == AlarmData) || (q->cmd == GridOnProFilePara))
|
||||||
|
incrAttempt(q->cmd == AlarmData? MORE_ATTEMPS_ALARMDATA : MORE_ATTEMPS_GRIDONPROFILEPARA);
|
||||||
|
mState = States::WAIT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case States::WAIT:
|
||||||
|
if (!q->iv->radio->mRadioWaitTime.isTimeout())
|
||||||
|
return;
|
||||||
|
mState = States::CHECK_FRAMES;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case States::CHECK_FRAMES: {
|
||||||
|
if((q->iv->radio->mBufCtrl.empty() && !mIsRetransmit) || (0 == q->attempts)) { // radio buffer empty or no more answers
|
||||||
|
if(*mSerialDebug) {
|
||||||
|
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||||
|
DBGPRINT(F("request timeout: "));
|
||||||
|
DBGPRINT(String(q->iv->radio->mRadioWaitTime.getRunTime()));
|
||||||
|
DBGPRINTLN(F("ms"));
|
||||||
|
}
|
||||||
|
if(!q->iv->mGotFragment) {
|
||||||
|
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 {
|
||||||
|
if(IV_MI == q->iv->ivGen)
|
||||||
|
q->iv->mIvTxCnt++;
|
||||||
|
if(mFirstTry) {
|
||||||
|
mFirstTry = false;
|
||||||
|
setAttempt();
|
||||||
|
mHeu.evalTxChQuality(q->iv, false, 0, 0);
|
||||||
|
//q->iv->radioStatistics.rxFailNoAnser++;
|
||||||
|
q->iv->radioStatistics.retransmits++;
|
||||||
|
q->iv->radio->mRadioWaitTime.stopTimeMonitor();
|
||||||
|
mState = States::START;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closeRequest(q, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mFirstTry = false; // for correct reset
|
||||||
|
if((IV_MI != q->iv->ivGen) || (0 == q->attempts))
|
||||||
|
mIsRetransmit = false;
|
||||||
|
|
||||||
|
while(!q->iv->radio->mBufCtrl.empty()) {
|
||||||
|
packet_t *p = &q->iv->radio->mBufCtrl.front();
|
||||||
|
|
||||||
|
if(validateIvSerial(&p->packet[1], q->iv)) {
|
||||||
|
printRxInfo(q, p);
|
||||||
|
q->iv->radioStatistics.frmCnt++;
|
||||||
|
q->iv->mDtuRxCnt++;
|
||||||
|
|
||||||
|
if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
|
||||||
|
if(parseFrame(p))
|
||||||
|
q->iv->curFrmCnt++;
|
||||||
|
} else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command
|
||||||
|
if(parseDevCtrl(p, q))
|
||||||
|
closeRequest(q, true);
|
||||||
|
else
|
||||||
|
closeRequest(q, false);
|
||||||
|
q->iv->radio->mBufCtrl.pop();
|
||||||
|
return; // don't wait for empty buffer
|
||||||
|
} else if(IV_MI == q->iv->ivGen) {
|
||||||
|
if(parseMiFrame(p, q))
|
||||||
|
q->iv->curFrmCnt++;
|
||||||
|
}
|
||||||
|
} //else -> serial does not match
|
||||||
|
|
||||||
|
q->iv->radio->mBufCtrl.pop();
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(q->iv->ivGen != IV_MI) {
|
||||||
|
mState = States::CHECK_PACKAGE;
|
||||||
|
} else {
|
||||||
|
bool fastNext = true;
|
||||||
|
if(q->iv->miMultiParts < 6) {
|
||||||
|
mState = States::WAIT;
|
||||||
|
if((q->iv->radio->mRadioWaitTime.isTimeout() && mIsRetransmit) || !mIsRetransmit) {
|
||||||
|
miRepeatRequest(q);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mHeu.evalTxChQuality(q->iv, true, (q->attemptsMax - 1 - q->attempts), q->iv->curFrmCnt);
|
||||||
|
if(((q->cmd == 0x39) && (q->iv->type == INV_TYPE_4CH))
|
||||||
|
|| ((q->cmd == MI_REQ_CH2) && (q->iv->type == INV_TYPE_2CH))
|
||||||
|
|| ((q->cmd == MI_REQ_CH1) && (q->iv->type == INV_TYPE_1CH))) {
|
||||||
|
miComplete(q->iv);
|
||||||
|
fastNext = false;
|
||||||
|
}
|
||||||
|
if(fastNext)
|
||||||
|
miNextRequest(q->iv->type == INV_TYPE_4CH ? MI_REQ_4CH : MI_REQ_CH1, q);
|
||||||
|
else
|
||||||
|
closeRequest(q, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case States::CHECK_PACKAGE:
|
||||||
|
uint8_t framnr = 0;
|
||||||
|
if(0 == mMaxFrameId) {
|
||||||
|
uint8_t i = 0;
|
||||||
|
while(i < MAX_PAYLOAD_ENTRIES) {
|
||||||
|
if(mLocalBuf[i].len == 0) {
|
||||||
|
framnr = i+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!framnr) {
|
||||||
|
for(uint8_t i = 0; i < mMaxFrameId; i++) {
|
||||||
|
if(mLocalBuf[i].len == 0) {
|
||||||
|
framnr = i+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(framnr) {
|
||||||
|
if(0 == q->attempts) {
|
||||||
|
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||||
|
DBGPRINT(F("no attempts left"));
|
||||||
|
closeRequest(q, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setAttempt();
|
||||||
|
|
||||||
|
if(*mSerialDebug) {
|
||||||
|
DPRINT_IVID(DBG_WARN, q->iv->id);
|
||||||
|
DBGPRINT(F("frame "));
|
||||||
|
DBGPRINT(String(framnr));
|
||||||
|
DBGPRINT(F(" missing: request retransmit ("));
|
||||||
|
DBGPRINT(String(q->attempts));
|
||||||
|
DBGPRINTLN(F(" attempts left)"));
|
||||||
|
}
|
||||||
|
if (!mIsRetransmit)
|
||||||
|
q->iv->mIsSingleframeReq = true;
|
||||||
|
sendRetransmit(q, (framnr-1));
|
||||||
|
mIsRetransmit = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
compilePayload(q);
|
||||||
|
|
||||||
|
if((NULL != mCbPayload) && (GridOnProFilePara != q->cmd) && (GetLossRate != q->cmd))
|
||||||
|
(mCbPayload)(q->cmd, q->iv);
|
||||||
|
|
||||||
|
closeRequest(q, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void printRxInfo(const queue_s *q, packet_t *p) {
|
inline void printRxInfo(const queue_s *q, packet_t *p) {
|
||||||
DPRINT_IVID(DBG_INFO, q->iv->id);
|
DPRINT_IVID(DBG_INFO, q->iv->id);
|
||||||
DBGPRINT(F("RX "));
|
DBGPRINT(F("RX "));
|
||||||
|
@ -1006,8 +1005,6 @@ class Communication : public CommQueue<> {
|
||||||
Heuristic mHeu;
|
Heuristic mHeu;
|
||||||
uint32_t mLastEmptyQueueMillis = 0;
|
uint32_t mLastEmptyQueueMillis = 0;
|
||||||
bool mPrintSequenceDuration = false;
|
bool mPrintSequenceDuration = false;
|
||||||
|
|
||||||
//States mDebugState = States::START;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__COMMUNICATION_H__*/
|
#endif /*__COMMUNICATION_H__*/
|
||||||
|
|
182
src/hm/hmRadio.h
182
src/hm/hmRadio.h
|
@ -48,8 +48,8 @@ class HmRadio : public Radio {
|
||||||
|
|
||||||
pinMode(irq, INPUT_PULLUP);
|
pinMode(irq, INPUT_PULLUP);
|
||||||
|
|
||||||
mSerialDebug = serialDebug;
|
mSerialDebug = serialDebug;
|
||||||
mPrivacyMode = privacyMode;
|
mPrivacyMode = privacyMode;
|
||||||
mPrintWholeTrace = printWholeTrace;
|
mPrintWholeTrace = printWholeTrace;
|
||||||
|
|
||||||
generateDtuSn();
|
generateDtuSn();
|
||||||
|
@ -78,7 +78,7 @@ class HmRadio : public Radio {
|
||||||
#else
|
#else
|
||||||
mNrf24->begin(mSpi.get(), ce, cs);
|
mNrf24->begin(mSpi.get(), ce, cs);
|
||||||
#endif
|
#endif
|
||||||
mNrf24->setRetries(3, 15); // 3*250us + 250us and 15 loops -> 15ms
|
mNrf24->setRetries(3, 15); // 3*250us + 250us and 16 loops -> 15.25ms
|
||||||
|
|
||||||
mNrf24->setChannel(mRfChLst[mRxChIdx]);
|
mNrf24->setChannel(mRfChLst[mRxChIdx]);
|
||||||
mNrf24->startListening();
|
mNrf24->startListening();
|
||||||
|
@ -89,10 +89,7 @@ class HmRadio : public Radio {
|
||||||
mNrf24->setCRCLength(RF24_CRC_16);
|
mNrf24->setCRCLength(RF24_CRC_16);
|
||||||
mNrf24->setAddressWidth(5);
|
mNrf24->setAddressWidth(5);
|
||||||
mNrf24->openReadingPipe(1, reinterpret_cast<uint8_t*>(&DTU_RADIO_ID));
|
mNrf24->openReadingPipe(1, reinterpret_cast<uint8_t*>(&DTU_RADIO_ID));
|
||||||
|
mNrf24->maskIRQ(false, false, false); // enable all receiving interrupts
|
||||||
// enable all receiving interrupts
|
|
||||||
mNrf24->maskIRQ(false, false, false);
|
|
||||||
|
|
||||||
mNrf24->setPALevel(1); // low is default
|
mNrf24->setPALevel(1); // low is default
|
||||||
|
|
||||||
if(mNrf24->isChipConnected()) {
|
if(mNrf24->isChipConnected()) {
|
||||||
|
@ -104,25 +101,23 @@ class HmRadio : public Radio {
|
||||||
DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring"));
|
DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop(void) {
|
// returns true if communication is active
|
||||||
|
bool loop(void) {
|
||||||
if (!mIrqRcvd && !mNRFisInRX)
|
if (!mIrqRcvd && !mNRFisInRX)
|
||||||
return; // first quick check => nothing to do at all here
|
return false; // first quick check => nothing to do at all here
|
||||||
|
|
||||||
if(NULL == mLastIv) // prevent reading on NULL object!
|
if(NULL == mLastIv) // prevent reading on NULL object!
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if(!mIrqRcvd) { // no news from nRF, check timers
|
if(!mIrqRcvd) { // no news from nRF, check timers
|
||||||
|
if ((millis() - mTimeslotStart) < innerLoopTimeout)
|
||||||
|
return true; // nothing to do, still waiting
|
||||||
|
|
||||||
if (mRadioWaitTime.isTimeout()) { // timeout reached!
|
if (mRadioWaitTime.isTimeout()) { // timeout reached!
|
||||||
mNRFisInRX = false;
|
mNRFisInRX = false;
|
||||||
// add stop listening?
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
yield();
|
|
||||||
|
|
||||||
if ((millis() - mTimeslotStart) < innerLoopTimeout)
|
|
||||||
return; // nothing to do
|
|
||||||
|
|
||||||
// otherwise switch to next RX channel
|
// otherwise switch to next RX channel
|
||||||
mTimeslotStart = millis();
|
mTimeslotStart = millis();
|
||||||
if(!mNRFloopChannels && ((mTimeslotStart - mLastIrqTime) > (DURATION_TXFRAME+DURATION_ONEFRAME)))
|
if(!mNRFloopChannels && ((mTimeslotStart - mLastIrqTime) > (DURATION_TXFRAME+DURATION_ONEFRAME)))
|
||||||
|
@ -140,60 +135,78 @@ class HmRadio : public Radio {
|
||||||
mNrf24->setChannel(mRfChLst[tempRxChIdx]);
|
mNrf24->setChannel(mRfChLst[tempRxChIdx]);
|
||||||
isRxInit = false;
|
isRxInit = false;
|
||||||
|
|
||||||
return;
|
return true; // communicating, but changed RX channel
|
||||||
}
|
} else {
|
||||||
|
// here we got news from the nRF
|
||||||
|
mIrqRcvd = false;
|
||||||
|
mNrf24->whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH
|
||||||
|
mLastIrqTime = millis();
|
||||||
|
|
||||||
// here we got news from the nRF
|
if(tx_ok || tx_fail) { // tx related interrupt, basically we should start listening
|
||||||
|
mNrf24->flush_tx(); // empty TX FIFO
|
||||||
|
mTxSetupTime = millis() - mMillis;
|
||||||
|
|
||||||
mNrf24->whatHappened(tx_ok, tx_fail, rx_ready); // resets the IRQ pin to HIGH
|
if(mNRFisInRX) {
|
||||||
mIrqRcvd = false;
|
DPRINTLN(DBG_WARN, F("unexpected tx irq!"));
|
||||||
mLastIrqTime = millis();
|
return false;
|
||||||
|
|
||||||
if(tx_ok || tx_fail) { // tx related interrupt, basically we should start listening
|
|
||||||
mNrf24->flush_tx(); // empty TX FIFO
|
|
||||||
|
|
||||||
if(mNRFisInRX) {
|
|
||||||
DPRINTLN(DBG_WARN, F("unexpected tx irq!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mNRFisInRX = true;
|
|
||||||
if(tx_ok)
|
|
||||||
mLastIv->mAckCount++;
|
|
||||||
|
|
||||||
// start listening
|
|
||||||
mRxChIdx = (mTxChIdx + 2 ) % RF_CHANNELS;
|
|
||||||
mNrf24->setChannel(mRfChLst[mRxChIdx]);
|
|
||||||
mNrf24->startListening();
|
|
||||||
mTimeslotStart = millis();
|
|
||||||
tempRxChIdx = mRxChIdx;
|
|
||||||
rxPendular = false;
|
|
||||||
mNRFloopChannels = mLastIv->ivGen == IV_MI;
|
|
||||||
|
|
||||||
innerLoopTimeout = DURATION_TXFRAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rx_ready) {
|
|
||||||
if (getReceived()) { // check what we got, returns true for last package
|
|
||||||
mNRFisInRX = false;
|
|
||||||
mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first end his transmissions
|
|
||||||
// add stop listening?
|
|
||||||
} else {
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mNRFisInRX = true;
|
||||||
|
if(tx_ok)
|
||||||
|
mLastIv->mAckCount++;
|
||||||
|
|
||||||
|
// start listening
|
||||||
|
if(!mIsRetransmit) {
|
||||||
|
if(mTxSetupTime < 30) {
|
||||||
|
mRxChIdx = (mTxChIdx + 4) % RF_CHANNELS;
|
||||||
|
mNrf24->setChannel(mRfChLst[mRxChIdx]);
|
||||||
|
mNrf24->startListening();
|
||||||
|
|
||||||
|
do {
|
||||||
|
yield();
|
||||||
|
} while((millis() - mMillis) < 37);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mIsRetransmit = false;
|
||||||
|
|
||||||
|
|
||||||
|
mRxChIdx = (mTxChIdx + 2) % RF_CHANNELS;
|
||||||
|
mNrf24->setChannel(mRfChLst[mRxChIdx]);
|
||||||
|
mNrf24->startListening();
|
||||||
|
mTimeslotStart = millis();
|
||||||
|
tempRxChIdx = mRxChIdx;
|
||||||
|
rxPendular = false;
|
||||||
|
mNRFloopChannels = (mLastIv->ivGen == IV_MI);
|
||||||
|
|
||||||
|
innerLoopTimeout = DURATION_TXFRAME;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
|
if(rx_ready) {
|
||||||
|
if (getReceived()) { // check what we got, returns true for last package
|
||||||
|
mNRFisInRX = false;
|
||||||
|
mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first end his transmissions
|
||||||
|
// add stop listening?
|
||||||
|
} else {
|
||||||
|
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 mNRFisInRX;
|
||||||
|
} /*else if(tx_fail) {
|
||||||
|
mNRFisInRX = false;
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isChipConnected(void) {
|
bool isChipConnected(void) {
|
||||||
|
@ -283,6 +296,7 @@ class HmRadio : public Radio {
|
||||||
}
|
}
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendPacket(iv, cnt, isRetransmit, (IV_MI != iv->ivGen));
|
sendPacket(iv, cnt, isRetransmit, (IV_MI != iv->ivGen));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,36 +312,38 @@ class HmRadio : public Radio {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline bool getReceived(void) {
|
inline bool getReceived(void) {
|
||||||
|
|
||||||
bool isLastPackage = false;
|
bool isLastPackage = false;
|
||||||
rx_ready = false; // reset for ACK case
|
rx_ready = false; // reset for ACK case
|
||||||
|
|
||||||
while(mNrf24->available()) {
|
while(mNrf24->available()) {
|
||||||
uint8_t len;
|
uint8_t len = mNrf24->getDynamicPayloadSize(); // payload size > 32 -> corrupt payload
|
||||||
len = mNrf24->getDynamicPayloadSize(); // if payload size > 32, corrupt payload has been flushed
|
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
packet_t p;
|
packet_t p;
|
||||||
p.ch = mRfChLst[tempRxChIdx];
|
p.ch = mRfChLst[tempRxChIdx];
|
||||||
p.len = (len > MAX_RF_PAYLOAD_SIZE) ? MAX_RF_PAYLOAD_SIZE : len;
|
p.len = (len > MAX_RF_PAYLOAD_SIZE) ? MAX_RF_PAYLOAD_SIZE : len;
|
||||||
p.rssi = mNrf24->testRPD() ? -64 : -75;
|
p.rssi = mNrf24->testRPD() ? -64 : -75;
|
||||||
p.millis = millis() - mMillis;
|
p.millis = millis() - mMillis;
|
||||||
mNrf24->read(p.packet, p.len);
|
mNrf24->read(p.packet, p.len);
|
||||||
|
|
||||||
if (p.packet[0] != 0x00) {
|
if (p.packet[0] != 0x00) {
|
||||||
if(!checkIvSerial(p.packet, mLastIv)) {
|
if(!checkIvSerial(p.packet, mLastIv)) {
|
||||||
DPRINT(DBG_WARN, "RX other inverter ");
|
DPRINT(DBG_WARN, "RX other inverter ");
|
||||||
if(*mPrivacyMode)
|
if(!*mPrivacyMode)
|
||||||
ah::dumpBuf(p.packet, p.len, 1, 4);
|
|
||||||
else
|
|
||||||
ah::dumpBuf(p.packet, p.len);
|
ah::dumpBuf(p.packet, p.len);
|
||||||
//return false;
|
|
||||||
} else {
|
} else {
|
||||||
mLastIv->mGotFragment = true;
|
mLastIv->mGotFragment = true;
|
||||||
mBufCtrl.push(p);
|
mBufCtrl.push(p);
|
||||||
|
|
||||||
if (p.packet[0] == (TX_REQ_INFO + ALL_FRAMES)) // response from get information command
|
if (p.packet[0] == (TX_REQ_INFO + ALL_FRAMES)) // response from get information command
|
||||||
isLastPackage = (p.packet[9] > ALL_FRAMES); // > ALL_FRAMES indicates last packet received
|
isLastPackage = (p.packet[9] > ALL_FRAMES); // > ALL_FRAMES indicates last packet received
|
||||||
else if (p.packet[0] == ( 0x0f + ALL_FRAMES) ) // response from MI get information command
|
|
||||||
isLastPackage = (p.packet[9] > 0x10); // > 0x10 indicates last packet received
|
if(IV_MI == mLastIv->ivGen) {
|
||||||
else if ((p.packet[0] != 0x88) && (p.packet[0] != 0x92)) // ignore MI status messages //#0 was p.packet[0] != 0x00 &&
|
if (p.packet[0] == (0x0f + ALL_FRAMES)) // response from MI get information command
|
||||||
isLastPackage = true; // response from dev control command
|
isLastPackage = (p.packet[9] > 0x10); // > 0x10 indicates last packet received
|
||||||
|
else if ((p.packet[0] != 0x88) && (p.packet[0] != 0x92)) // ignore MI status messages //#0 was p.packet[0] != 0x00 &&
|
||||||
|
isLastPackage = true; // response from dev control command
|
||||||
|
}
|
||||||
rx_ready = true; //reset in case we first read messages from other inverter or ACK zero payloads
|
rx_ready = true; //reset in case we first read messages from other inverter or ACK zero payloads
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,6 +363,12 @@ class HmRadio : public Radio {
|
||||||
mTxChIdx = iv->heuristics.txRfChId;
|
mTxChIdx = iv->heuristics.txRfChId;
|
||||||
|
|
||||||
if(*mSerialDebug) {
|
if(*mSerialDebug) {
|
||||||
|
if(!isRetransmit) {
|
||||||
|
DPRINT(DBG_INFO, "last tx setup: ");
|
||||||
|
DBGPRINT(String(mTxSetupTime));
|
||||||
|
DBGPRINTLN("ms");
|
||||||
|
}
|
||||||
|
|
||||||
DPRINT_IVID(DBG_INFO, iv->id);
|
DPRINT_IVID(DBG_INFO, iv->id);
|
||||||
DBGPRINT(F("TX "));
|
DBGPRINT(F("TX "));
|
||||||
DBGPRINT(String(len));
|
DBGPRINT(String(len));
|
||||||
|
@ -376,7 +398,7 @@ class HmRadio : public Radio {
|
||||||
mLastIv = iv;
|
mLastIv = iv;
|
||||||
iv->mDtuTxCnt++;
|
iv->mDtuTxCnt++;
|
||||||
mNRFisInRX = false;
|
mNRFisInRX = false;
|
||||||
mRqstGetRx = true; // preparation only
|
mIsRetransmit = isRetransmit;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t getIvId(Inverter<> *iv) {
|
uint64_t getIvId(Inverter<> *iv) {
|
||||||
|
@ -410,6 +432,8 @@ class HmRadio : public Radio {
|
||||||
bool isRxInit = true;
|
bool isRxInit = true;
|
||||||
bool rxPendular = false;
|
bool rxPendular = false;
|
||||||
uint32_t innerLoopTimeout = DURATION_LISTEN_MIN;
|
uint32_t innerLoopTimeout = DURATION_LISTEN_MIN;
|
||||||
|
uint8_t mTxSetupTime = 0;
|
||||||
|
bool mIsRetransmit = false;
|
||||||
|
|
||||||
std::unique_ptr<SPIClass> mSpi;
|
std::unique_ptr<SPIClass> mSpi;
|
||||||
std::unique_ptr<RF24> mNrf24;
|
std::unique_ptr<RF24> mNrf24;
|
||||||
|
|
|
@ -28,8 +28,7 @@ class Radio {
|
||||||
virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; }
|
virtual bool switchFrequency(Inverter<> *iv, uint32_t fromkHz, uint32_t tokHz) { return true; }
|
||||||
virtual bool switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) { return true; }
|
virtual bool switchFrequencyCh(Inverter<> *iv, uint8_t fromCh, uint8_t toCh) { return true; }
|
||||||
virtual bool isChipConnected(void) { return false; }
|
virtual bool isChipConnected(void) { return false; }
|
||||||
|
virtual bool loop(void) = 0;
|
||||||
virtual void loop(void) {};
|
|
||||||
|
|
||||||
void handleIntr(void) {
|
void handleIntr(void) {
|
||||||
mIrqRcvd = true;
|
mIrqRcvd = true;
|
||||||
|
@ -126,7 +125,6 @@ class Radio {
|
||||||
|
|
||||||
uint32_t mDtuSn;
|
uint32_t mDtuSn;
|
||||||
volatile bool mIrqRcvd;
|
volatile bool mIrqRcvd;
|
||||||
bool mRqstGetRx;
|
|
||||||
bool *mSerialDebug, *mPrivacyMode, *mPrintWholeTrace;
|
bool *mSerialDebug, *mPrivacyMode, *mPrintWholeTrace;
|
||||||
uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE];
|
uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE];
|
||||||
uint8_t mFramesExpected = 0x0c;
|
uint8_t mFramesExpected = 0x0c;
|
||||||
|
|
|
@ -26,15 +26,16 @@ class CmtRadio : public Radio {
|
||||||
mPrintWholeTrace = printWholeTrace;
|
mPrintWholeTrace = printWholeTrace;
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
bool loop() {
|
||||||
mCmt.loop();
|
mCmt.loop();
|
||||||
if((!mIrqRcvd) && (!mRqstGetRx))
|
if((!mIrqRcvd) && (!mRqstGetRx))
|
||||||
return;
|
return false;
|
||||||
getRx();
|
getRx();
|
||||||
if(CMT_SUCCESS == mCmt.goRx()) {
|
if(CMT_SUCCESS == mCmt.goRx()) {
|
||||||
mIrqRcvd = false;
|
mIrqRcvd = false;
|
||||||
mRqstGetRx = false;
|
mRqstGetRx = false;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isChipConnected(void) {
|
bool isChipConnected(void) {
|
||||||
|
@ -134,8 +135,8 @@ class CmtRadio : public Radio {
|
||||||
mCmt.goRx();
|
mCmt.goRx();
|
||||||
}
|
}
|
||||||
|
|
||||||
mIrqRcvd = false;
|
mIrqRcvd = false;
|
||||||
mRqstGetRx = false;
|
mRqstGetRx = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void sendSwitchChCmd(Inverter<> *iv, uint8_t ch) {
|
inline void sendSwitchChCmd(Inverter<> *iv, uint8_t ch) {
|
||||||
|
@ -163,11 +164,16 @@ class CmtRadio : public Radio {
|
||||||
uint8_t status = mCmt.getRx(p.packet, &p.len, 28, &p.rssi);
|
uint8_t status = mCmt.getRx(p.packet, &p.len, 28, &p.rssi);
|
||||||
if(CMT_SUCCESS == status)
|
if(CMT_SUCCESS == status)
|
||||||
mBufCtrl.push(p);
|
mBufCtrl.push(p);
|
||||||
|
|
||||||
|
// this code completly stops communication!
|
||||||
|
//if(p.packet[9] > ALL_FRAMES) // indicates last frame
|
||||||
|
// mRadioWaitTime.stopTimeMonitor(); // we got everything we expected and can exit rx mode...
|
||||||
|
//optionally instead: mRadioWaitTime.startTimeMonitor(DURATION_PAUSE_LASTFR); // let the inverter first get back to rx mode?
|
||||||
}
|
}
|
||||||
|
|
||||||
CmtType mCmt;
|
CmtType mCmt;
|
||||||
//bool mRqstGetRx;
|
|
||||||
bool mCmtAvail;
|
bool mCmtAvail;
|
||||||
|
bool mRqstGetRx = false;
|
||||||
uint32_t mMillis;
|
uint32_t mMillis;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,16 +20,14 @@
|
||||||
class TimeMonitor {
|
class TimeMonitor {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* A constructor for initializing a TimeMonitor
|
* A constructor for creating a TimeMonitor object
|
||||||
* @note TimeMonitor witch default constructor is stopped
|
|
||||||
*/
|
*/
|
||||||
TimeMonitor(void) {}
|
TimeMonitor(void) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A constructor for initializing a TimeMonitor
|
* A constructor for initializing a TimeMonitor object
|
||||||
* @param timeout timeout in ms
|
* @param timeout timeout in ms
|
||||||
* @param start (optional) if true, start TimeMonitor immediately
|
* @param start (optional) if true, start TimeMonitor immediately
|
||||||
* @note TimeMonitor witch default constructor is stopped
|
|
||||||
*/
|
*/
|
||||||
TimeMonitor(uint32_t timeout, bool start = false) {
|
TimeMonitor(uint32_t timeout, bool start = false) {
|
||||||
if (start)
|
if (start)
|
||||||
|
@ -50,7 +48,8 @@ class TimeMonitor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restart the TimeMonitor with already set timeout configuration
|
* Restart the TimeMonitor with already set timeout configuration
|
||||||
* @note returns nothing
|
* @note a timeout has to be set before, no need to call
|
||||||
|
* 'startTimeMonitor' before
|
||||||
*/
|
*/
|
||||||
void reStartTimeMonitor(void) {
|
void reStartTimeMonitor(void) {
|
||||||
mStartTime = millis();
|
mStartTime = millis();
|
||||||
|
@ -82,7 +81,7 @@ class TimeMonitor {
|
||||||
* false: TimeMonitor still in time or TimeMonitor was stopped
|
* false: TimeMonitor still in time or TimeMonitor was stopped
|
||||||
*/
|
*/
|
||||||
bool isTimeout(void) {
|
bool isTimeout(void) {
|
||||||
if ((mStarted) && (millis() - mStartTime >= mTimeout))
|
if ((mStarted) && ((millis() - mStartTime) >= mTimeout))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -104,7 +103,7 @@ class TimeMonitor {
|
||||||
*/
|
*/
|
||||||
uint32_t getResidualTime(void) const {
|
uint32_t getResidualTime(void) const {
|
||||||
uint32_t delayed = millis() - mStartTime;
|
uint32_t delayed = millis() - mStartTime;
|
||||||
return(mStarted ? (delayed < mTimeout ? mTimeout - delayed : 0UL) : 0xFFFFFFFFUL);
|
return(mStarted ? (delayed < mTimeout ? (mTimeout - delayed) : 0UL) : 0xFFFFFFFFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,4 +122,4 @@ class TimeMonitor {
|
||||||
bool mStarted = false; // start/stop state of the TimeMonitor
|
bool mStarted = false; // start/stop state of the TimeMonitor
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,3 +4,4 @@
|
||||||
<script type="text/javascript" src="api.js?v={#VERSION}"></script>
|
<script type="text/javascript" src="api.js?v={#VERSION}"></script>
|
||||||
<link rel="stylesheet" type="text/css" href="colors.css?v={#VERSION}"/>
|
<link rel="stylesheet" type="text/css" href="colors.css?v={#VERSION}"/>
|
||||||
<meta name="robots" content="noindex, nofollow" />
|
<meta name="robots" content="noindex, nofollow" />
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue