Browse Source

improved HMS and CMT configuration

reconnect on timeout (30s)
introduced frequency ranges for EU
pull/935/head
lumapu 2 years ago
parent
commit
c4e20b6395
  1. 162
      src/hms/cmt2300a.h
  2. 14
      src/hms/hmsPayload.h
  3. 71
      src/hms/hmsRadio.h

162
src/hms/cmt2300a.h

@ -8,6 +8,15 @@
#include "esp32_3wSpi.h"
#define WORK_FREQ_KHZ 865000 // disired work frequency between DTU and
// inverter in kHz
#define HOY_BASE_FREQ_KHZ 860000 // in kHz
#define HOY_MAX_FREQ_KHZ 923500 // 0xFE * 250kHz + Base_freq
#define HOY_BOOT_FREQ_KHZ 868000 // Hoymiles boot/init frequency after power up inverter
#define FREQ_STEP_KHZ 250 // channel step size in kHz
#define FREQ_WARN_MIN_KHZ 863000 // for EU 863 - 870 MHz is allowed
#define FREQ_WARN_MAX_KHZ 870000 // for EU 863 - 870 MHz is allowed
// detailed register infos from AN142_CMT2300AW_Quick_Start_Guide-Rev0.8.pdf
#define CMT2300A_MASK_CFG_RETAIN 0x10
@ -144,24 +153,24 @@
// default CMT paramters
static uint8_t cmtConfig[0x60] PROGMEM {
// 0x00 - 0x0f
0x00, 0x66, 0xEC, 0x1D, 0x70, 0x80, 0x14, 0x08,
0x91, 0x02, 0x02, 0xD0, 0xAE, 0xE0, 0x35, 0x00,
// 0x00 - 0x0f -- RSSI offset +- 0 and 13dBm
0x00, 0x66, 0xEC, 0x1C, 0x70, 0x80, 0x14, 0x08,
0x11, 0x02, 0x02, 0x00, 0xAE, 0xE0, 0x35, 0x00,
// 0x10 - 0x1f
0x00, 0xF4, 0x10, 0xE2, 0x42, 0x20, 0x0C, 0x81,
0x42, 0x6D, 0x80, 0x86, 0x42, 0x62, 0x27, 0x16, // 0x42, 0xCF, 0xA7, 0x8C, 0x42, 0xC4, 0x4E, 0x1C,
0x42, 0x32, 0xCF, 0x82, 0x42, 0x27, 0x76, 0x12, // 860MHz as default
// 0x20 - 0x2f
0xA6, 0xC9, 0x20, 0x20, 0xD2, 0x35, 0x0C, 0x0A,
0x9F, 0x4B, 0x0A, 0x29, 0xC0, 0x14, 0x05, 0x53, // 0x9F, 0x4B, 0x29, 0x29, 0xC0, 0x14, 0x05, 0x53,
0x9F, 0x4B, 0x29, 0x29, 0xC0, 0x14, 0x05, 0x53,
// 0x30 - 0x3f
0x10, 0x00, 0xB4, 0x00, 0x00, 0x01, 0x00, 0x00,
0x12, 0x1E, 0x00, 0xAA, 0x06, 0x00, 0x00, 0x00,
// 0x40 - 0x4f
0x00, 0x48, 0x5A, 0x48, 0x4D, 0x01, 0x1D, 0x00, // 0x00, 0xD6, 0xD5, 0xD4, 0x2D, 0x01, 0x1D, 0x00,
0x00, 0x48, 0x5A, 0x48, 0x4D, 0x01, 0x1D, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x60,
// 0x50 - 0x5f
// 0x50 - 0x5f - TX 13dBm
0xFF, 0x00, 0x00, 0x1F, 0x10, 0x70, 0x4D, 0x06,
0x00, 0x07, 0x50, 0x00, 0x8A, 0x18, 0x3F, 0x7F
0x00, 0x07, 0x50, 0x00, 0x42, 0x0C, 0x3F, 0x7F
};
enum {CMT_SUCCESS = 0, CMT_ERR_SWITCH_STATE, CMT_ERR_TX_PENDING, CMT_FIFO_EMPTY, CMT_ERR_RX_IN_FIFO};
@ -215,10 +224,7 @@ class Cmt2300a {
else
mSpi.writeReg(CMT2300A_CUS_INT_CLR2, 0x00);
//mSpi.readReg(CMT2300A_CUS_FIFO_CTL); // necessary? -> if 0x02 last was read
// 0x07 last was write
mSpi.writeReg(CMT2300A_CUS_FIFO_CTL, 0x02);
mSpi.writeReg(CMT2300A_CUS_FIFO_CLR, 0x02);
mSpi.writeReg(0x16, 0x0C); // [4:3]: RSSI_DET_SEL, [2:0]: RSSI_AVG_MODE
@ -272,33 +278,28 @@ class Cmt2300a {
mSpi.writeReg(CMT2300A_CUS_INT1_CTL, CMT2300A_INT_SEL_TX_DONE);
//mCusIntFlag == mSpi.readReg(CMT2300A_CUS_INT_FLAG);
//if(0x00 == mCusIntFlag) {
// no data received
mSpi.readReg(CMT2300A_CUS_INT_CLR1);
mSpi.writeReg(CMT2300A_CUS_INT_CLR1, 0x00);
mSpi.writeReg(CMT2300A_CUS_INT_CLR2, 0x00);
// no data received
mSpi.readReg(CMT2300A_CUS_INT_CLR1);
mSpi.writeReg(CMT2300A_CUS_INT_CLR1, 0x00);
mSpi.writeReg(CMT2300A_CUS_INT_CLR2, 0x00);
//mSpi.readReg(CMT2300A_CUS_FIFO_CTL); // necessary?
mSpi.writeReg(CMT2300A_CUS_FIFO_CTL, 0x07);
mSpi.writeReg(CMT2300A_CUS_FIFO_CLR, 0x01);
//mSpi.readReg(CMT2300A_CUS_FIFO_CTL); // necessary?
mSpi.writeReg(CMT2300A_CUS_FIFO_CTL, 0x07);
mSpi.writeReg(CMT2300A_CUS_FIFO_CLR, 0x01);
mSpi.writeReg(0x45, 0x01);
mSpi.writeReg(0x46, len); // payload length
mSpi.writeReg(0x45, 0x01);
mSpi.writeReg(0x46, len); // payload length
mSpi.writeFifo(buf, len);
mSpi.writeFifo(buf, len);
// send only on base frequency: here 863.0 MHz
swichChannel((len != 15));
// send only on base frequency: here 863.0 MHz
//switchChannel((len != 15));
if(!cmtSwitchStatus(CMT2300A_GO_TX, CMT2300A_STA_TX))
return CMT_ERR_SWITCH_STATE;
if(!cmtSwitchStatus(CMT2300A_GO_TX, CMT2300A_STA_TX))
return CMT_ERR_SWITCH_STATE;
// wait for tx done
mTxPending = true;
//}
//else
// return CMT_ERR_RX_IN_FIFO;
// wait for tx done
mTxPending = true;
return CMT_SUCCESS;
}
@ -311,25 +312,13 @@ class Cmt2300a {
if(!cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY))
return false;
//if(0xAA != mSpi.readReg(0x48))
// mSpi.writeReg(0x48, 0xAA);
//mSpi.readReg(0x48);
//mSpi.writeReg(0x4c, 0x00);
//if(0x52 != mSpi.readReg(CMT2300A_CUS_MODE_STA))
mSpi.writeReg(CMT2300A_CUS_MODE_STA, 0x52);
//if(0x20 != mSpi.readReg(0x62))
mSpi.writeReg(0x62, 0x20);
//mSpi.readReg(0x0D);
//mSpi.writeReg(0x0F, 0x00);
mSpi.writeReg(CMT2300A_CUS_MODE_STA, 0x52);
mSpi.writeReg(0x62, 0x20);
for(uint8_t i = 0; i < 0x60; i++) {
mSpi.writeReg(i, cmtConfig[i]);
}
//if(0x02 != mSpi.readReg(0x09))
// mSpi.writeReg(0x09, 0x02);
mSpi.writeReg(CMT2300A_CUS_IO_SEL, 0x20); // -> GPIO3_SEL[1:0] = 0x02
// interrupt 1 control selection to TX DONE
@ -343,10 +332,6 @@ class Cmt2300a {
// interrupt enable (TX_DONE, PREAM_OK, SYNC_OK, CRC_OK, PKT_DONE)
mSpi.writeReg(CMT2300A_CUS_INT_EN, 0x3B);
/*mSpi.writeReg(0x41, 0x48);
mSpi.writeReg(0x42, 0x5A);
mSpi.writeReg(0x43, 0x48);
mSpi.writeReg(0x44, 0x4D);*/
mSpi.writeReg(0x64, 0x64);
if(0x00 == mSpi.readReg(CMT2300A_CUS_FIFO_CTL))
@ -357,43 +342,44 @@ class Cmt2300a {
delayMicroseconds(95);
// base frequency 863MHz; with value of CMT2300A_CUS_FREQ_CHNL
// the frequency can be increased in a step size of ~0.24Hz
/*mSpi.writeReg(0x18, 0x42);
mSpi.writeReg(0x19, 0x6D);
mSpi.writeReg(0x1A, 0x80);
mSpi.writeReg(0x1B, 0x86);
mSpi.writeReg(0x1C, 0x42);
mSpi.writeReg(0x1D, 0x62);
mSpi.writeReg(0x1E, 0x27);
mSpi.writeReg(0x1F, 0x16);*/
/*mSpi.writeReg(0x22, 0x20);
mSpi.writeReg(0x23, 0x20);
mSpi.writeReg(0x24, 0xD2);
mSpi.writeReg(0x25, 0x35);
mSpi.writeReg(0x26, 0x0C);
mSpi.writeReg(0x27, 0x0A);
mSpi.writeReg(0x28, 0x9F);
mSpi.writeReg(0x29, 0x4B);
mSpi.writeReg(0x27, 0x0A);*/
if(!cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY))
return false;
/*mSpi.writeReg(0x03, 0x1D);
mSpi.writeReg(0x5C, 0x8A);
mSpi.writeReg(0x5D, 0x18);*/
if(!cmtSwitchStatus(CMT2300A_GO_SLEEP, CMT2300A_STA_SLEEP))
return false;
if(!cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY))
return false;
switchDtuFreq(WORK_FREQ_KHZ);
return true;
}
inline uint8_t freq2Chan(const uint32_t freqKhz) {
if((freqKhz % FREQ_STEP_KHZ) != 0) {
DPRINT(DBG_WARN, F("swtich frequency to "));
DBGPRINT(String(freqKhz));
DBGPRINT(F("kHz not possible!"));
return 0xff; // error
// apply the nearest frequency
//freqKhz = (freqKhz + FREQ_STEP_KHZ/2) / FREQ_STEP_KHZ;
//freqKhz *= FREQ_STEP_KHZ;
}
if((freqKhz < HOY_BASE_FREQ_KHZ) || (freqKhz > HOY_MAX_FREQ_KHZ))
return 0xff; // error
if((freqKhz < FREQ_WARN_MIN_KHZ) || (freqKhz > FREQ_WARN_MAX_KHZ))
DPRINTLN(DBG_WARN, F("Disired frequency is out of EU legal range! (863 - 870MHz)"));
return (freqKhz - HOY_BASE_FREQ_KHZ) / FREQ_STEP_KHZ;
}
inline void switchChannel(uint8_t ch) {
mSpi.writeReg(CMT2300A_CUS_FREQ_CHNL, ch);
}
private:
void init() {
mTxPending = false;
@ -415,23 +401,14 @@ class Cmt2300a {
return false;
}
inline void swichChannel(bool def = true, uint8_t start = 0x00, uint8_t end = 0x22) {
if(!def) {
if(++mCnt > 2) {
if(++mRxTxCh > end)
mRxTxCh = start;
mCnt = 0;
}
}
// 0: 868.00MHz
// 1: 868.23MHz
// 2: 868.46MHz
// 3: 868.72MHz
// 4: 868.97MHz
if(!def)
mSpi.writeReg(CMT2300A_CUS_FREQ_CHNL, mRxTxCh);
else
mSpi.writeReg(CMT2300A_CUS_FREQ_CHNL, 0x00);
inline bool switchDtuFreq(const uint32_t freqKhz) {
uint8_t toCh = freq2Chan(freqKhz);
if(0xff == toCh)
return false;
switchChannel(toCh);
return true;
}
inline uint8_t getChipStatus(void) {
@ -441,7 +418,6 @@ class Cmt2300a {
SpiType mSpi;
uint8_t mCnt;
bool mTxPending;
uint8_t mRxTxCh;
bool mInRxMode;
uint8_t mCusIntFlag;
};

14
src/hms/hmsPayload.h

@ -11,6 +11,8 @@
#include "../config/config.h"
#include <Arduino.h>
#define HMS_TIMEOUT_MS 30000 // 30s * 1000
typedef struct {
uint8_t txCmd;
uint8_t txId;
@ -50,7 +52,7 @@ class HmsPayload {
//mHighPrioIv = NULL;
mCbAlarm = NULL;
mCbPayload = NULL;
mFirst = true;
mLastRx = 0;
}
void enableSerialDebug(bool enable) {
@ -137,9 +139,10 @@ class HmsPayload {
mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false);
mPayload[iv->id].txCmd = cmd;
}*/
if(mFirst) {
mFirst = false;
mRadio->setIvBackChannel(&iv->radioId.u64);
DPRINT(DBG_INFO, "LastRx: ");
DBGPRINTLN(String(mLastRx));
if((mLastRx + HMS_TIMEOUT_MS) < millis()) {
mRadio->switchFrequency(&iv->radioId.u64, HOY_BOOT_FREQ_KHZ, WORK_FREQ_KHZ);
} else {
uint8_t cmd = iv->getQueuedCmd();
DPRINT(DBG_INFO, F("(#"));
@ -151,6 +154,7 @@ class HmsPayload {
}
void add(Inverter<> *iv, hmsPacket_t *p) {
mLastRx = millis();
if (p->data[1] == (TX_REQ_INFO + ALL_FRAMES)) { // response from get information command
mPayload[iv->id].txId = p->data[1];
DPRINTLN(DBG_DEBUG, F("Response from info request received"));
@ -398,10 +402,10 @@ class HmsPayload {
statistics_t *mStat;
uint8_t mMaxRetrans;
uint32_t *mTimestamp;
uint32_t mLastRx;
hmsPayload_t mPayload[MAX_NUM_INVERTERS];
bool mSerialDebug;
Inverter<> *mHighPrioIv;
bool mFirst;
alarmListenerType mCbAlarm;
payloadListenerType mCbPayload;

71
src/hms/hmsRadio.h

@ -41,12 +41,6 @@ class CmtRadio {
bool loop() {
mCmt.loop();
if(++mCnt > 30000) {
mCnt = 0;
if(NULL != mIvIdChannelSet)
prepareSwitchChannelCmd(mIvIdChannelSet);
}
if(!mIrqRcvd)
return false;
mIrqRcvd = false;
@ -66,14 +60,17 @@ class CmtRadio {
mSerialDebug = true;
}
void setIvBackChannel(const uint64_t *ivId) {
mIvIdChannelSet = ivId;
Serial.println("Byte 3 " + String(U32_B3((*mIvIdChannelSet) >> 8), HEX));
Serial.println("Byte 2 " + String(U32_B2((*mIvIdChannelSet) >> 8), HEX));
Serial.println("Byte 1 " + String(U32_B1((*mIvIdChannelSet) >> 8), HEX));
Serial.println("Byte 0 " + String(U32_B0((*mIvIdChannelSet) >> 8), HEX));
prepareSwitchChannelCmd(mIvIdChannelSet);
bool switchFrequency(const uint64_t *ivId, uint32_t fromkHz, uint32_t tokHz) {
uint8_t fromCh = mCmt.freq2Chan(fromkHz);
uint8_t toCh = mCmt.freq2Chan(tokHz);
if((0xff == fromCh) || (0xff == toCh))
return false;
mCmt.switchChannel(fromCh);
sendSwitchChCmd(ivId, toCh);
mCmt.switchChannel(toCh);
return true;
}
void prepareDevInformCmd(const 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.
@ -87,22 +84,6 @@ class CmtRadio {
sendPacket(24, isRetransmit);
}
inline void prepareSwitchChannelCmd(const uint64_t *ivId, uint8_t freqSel = 0x0c) {
/** freqSel:
* 0x0c: 863.00 MHz
* 0x0d: 863.24 MHz
* 0x0e: 863.48 MHz
* 0x0f: 863.72 MHz
* 0x10: 863.96 MHz
* */
initPacket(ivId, 0x56, 0x02);
mTxBuf[10] = 0x15;
mTxBuf[11] = 0x21;
mTxBuf[12] = freqSel;
mTxBuf[13] = 0x14;
sendPacket(14, false);
}
void sendPacket(uint8_t len, bool isRetransmit) {
if (len > 14) {
uint16_t crc = ah::crc16(&mTxBuf[10], len - 10);
@ -149,9 +130,23 @@ class CmtRadio {
mSendCnt = 0;
mRetransmits = 0;
mSerialDebug = false;
mIvIdChannelSet = NULL;
mIrqRcvd = false;
mCnt = 0;
}
inline void sendSwitchChCmd(const uint64_t *ivId, uint8_t ch) {
/** ch:
* 0x0c: 863.00 MHz
* 0x0d: 863.24 MHz
* 0x0e: 863.48 MHz
* 0x0f: 863.72 MHz
* 0x10: 863.96 MHz
* */
initPacket(ivId, 0x56, 0x02);
mTxBuf[10] = 0x15;
mTxBuf[11] = 0x21;
mTxBuf[12] = ch;
mTxBuf[13] = 0x14;
sendPacket(14, false);
}
void initPacket(const uint64_t *ivId, uint8_t mid, uint8_t pid) {
@ -180,27 +175,13 @@ class CmtRadio {
uint8_t status = mCmt.getRx(p.data, 28, &p.rssi);
if(CMT_SUCCESS == status)
mBufCtrl.push(p);
if(NULL != mIvIdChannelSet) {
if(U32_B3((*mIvIdChannelSet) >> 8) != p.data[5])
return;
if(U32_B2((*mIvIdChannelSet) >> 8) != p.data[4])
return;
if(U32_B1((*mIvIdChannelSet) >> 8) != p.data[3])
return;
if(U32_B0((*mIvIdChannelSet) >> 8) != p.data[2])
return;
mIvIdChannelSet = NULL;
}
}
CmtType mCmt;
uint32_t mDtuSn;
uint8_t mTxBuf[27];
bool mSerialDebug;
const uint64_t *mIvIdChannelSet;
bool mIrqRcvd;
uint16_t mCnt;
};
#endif /*__HMS_RADIO_H__*/

Loading…
Cancel
Save