mirror of https://github.com/lumapu/ahoy.git
116 lines
4.1 KiB
116 lines
4.1 KiB
//-----------------------------------------------------------------------------
|
|
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef __RADIO_H__
|
|
#define __RADIO_H__
|
|
|
|
#define TX_REQ_INFO 0x15
|
|
#define TX_REQ_DEVCONTROL 0x51
|
|
#define ALL_FRAMES 0x80
|
|
#define SINGLE_FRAME 0x81
|
|
|
|
#include "../utils/dbg.h"
|
|
#include "../utils/crc.h"
|
|
|
|
// forward declaration of class
|
|
template <class REC_TYP=float>
|
|
class Inverter;
|
|
|
|
// abstract radio interface
|
|
class Radio {
|
|
public:
|
|
virtual void sendControlPacket(Inverter<> *iv, uint8_t cmd, uint16_t *data, bool isRetransmit) = 0;
|
|
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 void loop(void) {};
|
|
|
|
bool get() {
|
|
return !mBufCtrl.empty();
|
|
}
|
|
|
|
void handleIntr(void) {
|
|
mIrqRcvd = true;
|
|
}
|
|
|
|
void sendCmdPacket(Inverter<> *iv, uint8_t mid, uint8_t pid, bool isRetransmit, bool appendCrc16=true) {
|
|
initPacket(getIvId(iv), mid, pid);
|
|
sendPacket(iv, 10, isRetransmit, appendCrc16);
|
|
}
|
|
|
|
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(IV_MI == getIvGen(iv)) {
|
|
DPRINT(DBG_DEBUG, F("legacy cmd 0x"));
|
|
DPRINTLN(DBG_DEBUG,String(cmd, HEX));
|
|
sendCmdPacket(iv, cmd, cmd, false, false);
|
|
return;
|
|
}
|
|
|
|
if(*mSerialDebug) {
|
|
DPRINT(DBG_DEBUG, F("prepareDevInformCmd 0x"));
|
|
DPRINTLN(DBG_DEBUG,String(cmd, HEX));
|
|
}
|
|
initPacket(getIvId(iv), reqfld, ALL_FRAMES);
|
|
mTxBuf[10] = cmd;
|
|
CP_U32_LittleEndian(&mTxBuf[12], ts);
|
|
if (cmd == AlarmData ) { //cmd == RealTimeRunData_Debug ||
|
|
mTxBuf[18] = (alarmMesId >> 8) & 0xff;
|
|
mTxBuf[19] = (alarmMesId ) & 0xff;
|
|
}
|
|
sendPacket(iv, 24, isRetransmit);
|
|
}
|
|
|
|
public:
|
|
std::queue<packet_t> mBufCtrl;
|
|
|
|
protected:
|
|
virtual void sendPacket(Inverter<> *iv, uint8_t len, bool isRetransmit, bool appendCrc16=true) = 0;
|
|
virtual uint64_t getIvId(Inverter<> *iv) = 0;
|
|
virtual uint8_t getIvGen(Inverter<> *iv) = 0;
|
|
|
|
void initPacket(uint64_t ivId, uint8_t mid, uint8_t pid) {
|
|
mTxBuf[0] = mid;
|
|
CP_U32_BigEndian(&mTxBuf[1], ivId >> 8);
|
|
CP_U32_LittleEndian(&mTxBuf[5], mDtuSn);
|
|
mTxBuf[9] = pid;
|
|
memset(&mTxBuf[10], 0x00, (MAX_RF_PAYLOAD_SIZE-10));
|
|
}
|
|
|
|
void updateCrcs(uint8_t *len, bool appendCrc16=true) {
|
|
// append crc's
|
|
if (appendCrc16 && ((*len) > 10)) {
|
|
// crc control data
|
|
uint16_t crc = ah::crc16(&mTxBuf[10], (*len) - 10);
|
|
mTxBuf[(*len)++] = (crc >> 8) & 0xff;
|
|
mTxBuf[(*len)++] = (crc ) & 0xff;
|
|
}
|
|
// crc over all
|
|
mTxBuf[*len] = ah::crc8(mTxBuf, *len);
|
|
(*len)++;
|
|
}
|
|
|
|
void generateDtuSn(void) {
|
|
uint32_t chipID = 0;
|
|
#ifdef ESP32
|
|
uint64_t MAC = ESP.getEfuseMac();
|
|
chipID = ((MAC >> 8) & 0xFF0000) | ((MAC >> 24) & 0xFF00) | ((MAC >> 40) & 0xFF);
|
|
#else
|
|
chipID = ESP.getChipId();
|
|
#endif
|
|
mDtuSn = 0x80000000; // the first digit is an 8 for DTU production year 2022, the rest is filled with the ESP chipID in decimal
|
|
for(int i = 0; i < 7; i++) {
|
|
mDtuSn |= (chipID % 10) << (i * 4);
|
|
chipID /= 10;
|
|
}
|
|
}
|
|
|
|
uint32_t mDtuSn;
|
|
volatile bool mIrqRcvd;
|
|
bool *mSerialDebug;
|
|
bool *mPrivacyMode;
|
|
uint8_t mTxBuf[MAX_RF_PAYLOAD_SIZE];
|
|
|
|
};
|
|
|
|
#endif /*__RADIO_H__*/
|
|
|