mirror of
https://github.com/lumapu/ahoy.git
synced 2025-06-16 09:31:39 +02:00
basic implementation of HMS/HMT inverters
This commit is contained in:
parent
b6a41506b6
commit
c56c785a1f
13 changed files with 800 additions and 19 deletions
|
@ -7,6 +7,7 @@
|
||||||
* added part of mac address to MQTT client ID to seperate multiple ESPs in same network
|
* added part of mac address to MQTT client ID to seperate multiple ESPs in same network
|
||||||
* added dictionary for MQTT to reduce heap-fragmentation
|
* added dictionary for MQTT to reduce heap-fragmentation
|
||||||
* removed `last Alarm` from Live view, because it showed always the same alarm - will change in future
|
* removed `last Alarm` from Live view, because it showed always the same alarm - will change in future
|
||||||
|
* #671, #650
|
||||||
|
|
||||||
## 0.5.88
|
## 0.5.88
|
||||||
* MQTT Yield Day zero, next try to fix #671, thx @beegee3
|
* MQTT Yield Day zero, next try to fix #671, thx @beegee3
|
||||||
|
|
|
@ -115,7 +115,7 @@ void app::loopStandard(void) {
|
||||||
DBGPRINT(F("B Ch"));
|
DBGPRINT(F("B Ch"));
|
||||||
DBGPRINT(String(p->ch));
|
DBGPRINT(String(p->ch));
|
||||||
DBGPRINT(F(" | "));
|
DBGPRINT(F(" | "));
|
||||||
mSys.Radio.dumpBuf(p->packet, p->len);
|
ah::dumpBuf(p->packet, p->len);
|
||||||
}
|
}
|
||||||
mStat.frmCnt++;
|
mStat.frmCnt++;
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,10 @@ class app : public IApp, public ah::Scheduler {
|
||||||
mSys.Radio.handleIntr();
|
mSys.Radio.handleIntr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleHmsIntr(void) {
|
||||||
|
//mSys.Radio.handleHmsIntr();
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t getUptime() {
|
uint32_t getUptime() {
|
||||||
return Scheduler::getUptime();
|
return Scheduler::getUptime();
|
||||||
}
|
}
|
||||||
|
@ -160,6 +164,10 @@ class app : public IApp, public ah::Scheduler {
|
||||||
return mConfig->nrf.pinIrq;
|
return mConfig->nrf.pinIrq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t getHmsIrqPin(void) {
|
||||||
|
return mConfig->cmt.pinIrq;
|
||||||
|
}
|
||||||
|
|
||||||
String getTimeStr(uint32_t offset = 0) {
|
String getTimeStr(uint32_t offset = 0) {
|
||||||
char str[10];
|
char str[10];
|
||||||
if(0 == mTimestamp)
|
if(0 == mTimestamp)
|
||||||
|
|
|
@ -68,6 +68,12 @@ typedef struct {
|
||||||
uint8_t amplifierPower;
|
uint8_t amplifierPower;
|
||||||
} cfgNrf24_t;
|
} cfgNrf24_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t pinCsb;
|
||||||
|
uint8_t pinFcsb;
|
||||||
|
uint8_t pinIrq;
|
||||||
|
} cfgCmt_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char addr[NTP_ADDR_LEN];
|
char addr[NTP_ADDR_LEN];
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
|
@ -138,6 +144,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
cfgSys_t sys;
|
cfgSys_t sys;
|
||||||
cfgNrf24_t nrf;
|
cfgNrf24_t nrf;
|
||||||
|
cfgCmt_t cmt;
|
||||||
cfgNtp_t ntp;
|
cfgNtp_t ntp;
|
||||||
cfgSun_t sun;
|
cfgSun_t sun;
|
||||||
cfgSerial_t serial;
|
cfgSerial_t serial;
|
||||||
|
|
430
src/hm/cmt2300a.h
Normal file
430
src/hm/cmt2300a.h
Normal file
|
@ -0,0 +1,430 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __CMT2300A_H__
|
||||||
|
#define __CMT2300A_H__
|
||||||
|
|
||||||
|
#include "esp32_3wSpi.h"
|
||||||
|
|
||||||
|
// detailed register infos from AN142_CMT2300AW_Quick_Start_Guide-Rev0.8.pdf
|
||||||
|
|
||||||
|
#define CMT2300A_CUS_MODE_CTL 0x60 // [7] go_switch
|
||||||
|
// [6] go_tx
|
||||||
|
// [5] go_tfs
|
||||||
|
// [4] go_sleep
|
||||||
|
// [3] go_rx
|
||||||
|
// [2] go_rfs
|
||||||
|
// [1] go_stby
|
||||||
|
// [0] n/a
|
||||||
|
|
||||||
|
#define CMT2300A_CUS_MODE_STA 0x61 // [3:0] 0x00 IDLE
|
||||||
|
// 0x01 SLEEP
|
||||||
|
// 0x02 STBY
|
||||||
|
// 0x03 RFS
|
||||||
|
// 0x04 TFS
|
||||||
|
// 0x05 RX
|
||||||
|
// 0x06 TX
|
||||||
|
// 0x08 UNLOCKED/LOW_VDD
|
||||||
|
// 0x09 CAL
|
||||||
|
#define CMT2300A_CUS_EN_CTL 0x62
|
||||||
|
#define CMT2300A_CUS_FREQ_CHNL 0x63
|
||||||
|
|
||||||
|
#define CMT2300A_CUS_IO_SEL 0x65 // [5:4] GPIO3
|
||||||
|
// 0x00 CLKO
|
||||||
|
// 0x01 DOUT / DIN
|
||||||
|
// 0x02 INT2
|
||||||
|
// 0x03 DCLK
|
||||||
|
// [3:2] GPIO2
|
||||||
|
// 0x00 INT1
|
||||||
|
// 0x01 INT2
|
||||||
|
// 0x02 DOUT / DIN
|
||||||
|
// 0x03 DCLK
|
||||||
|
// [1:0] GPIO1
|
||||||
|
// 0x00 DOUT / DIN
|
||||||
|
// 0x01 INT1
|
||||||
|
// 0x02 INT2
|
||||||
|
// 0x03 DCLK
|
||||||
|
|
||||||
|
#define CMT2300A_CUS_INT1_CTL 0x66 // [4:0] INT1_SEL
|
||||||
|
// 0x00 RX active
|
||||||
|
// 0x01 TX active
|
||||||
|
// 0x02 RSSI VLD
|
||||||
|
// 0x03 Pream OK
|
||||||
|
// 0x04 SYNC OK
|
||||||
|
// 0x05 NODE OK
|
||||||
|
// 0x06 CRC OK
|
||||||
|
// 0x07 PKT OK
|
||||||
|
// 0x08 SL TMO
|
||||||
|
// 0x09 RX TMO
|
||||||
|
// 0x0A TX DONE
|
||||||
|
// 0x0B RX FIFO NMTY
|
||||||
|
// 0x0C RX FIFO TH
|
||||||
|
// 0x0D RX FIFO FULL
|
||||||
|
// 0x0E RX FIFO WBYTE
|
||||||
|
// 0x0F RX FIFO OVF
|
||||||
|
// 0x10 TX FIFO NMTY
|
||||||
|
// 0x11 TX FIFO TH
|
||||||
|
// 0x12 TX FIFO FULL
|
||||||
|
// 0x13 STATE IS STBY
|
||||||
|
// 0x14 STATE IS FS
|
||||||
|
// 0x15 STATE IS RX
|
||||||
|
// 0x16 STATE IS TX
|
||||||
|
// 0x17 LED
|
||||||
|
// 0x18 TRX ACTIVE
|
||||||
|
// 0x19 PKT DONE
|
||||||
|
|
||||||
|
#define CMT2300A_CUS_INT2_CTL 0x67 // [4:0] INT2_SEL
|
||||||
|
|
||||||
|
#define CMT2300A_CUS_INT_EN 0x68 // [7] SL TMO EN
|
||||||
|
// [6] RX TMO EN
|
||||||
|
// [5] TX DONE EN
|
||||||
|
// [4] PREAM OK EN
|
||||||
|
// [3] SYNC_OK EN
|
||||||
|
// [2] NODE OK EN
|
||||||
|
// [1] CRC OK EN
|
||||||
|
// [0] PKT DONE EN
|
||||||
|
|
||||||
|
#define CMT2300A_CUS_FIFO_CTL 0x69 // [7] TX DIN EN
|
||||||
|
// [6:5] TX DIN SEL
|
||||||
|
// 0x00 SEL GPIO1
|
||||||
|
// 0x01 SEL GPIO2
|
||||||
|
// 0x02 SEL GPIO3
|
||||||
|
// [4] FIFO AUTO CLR DIS
|
||||||
|
// [3] FIFO TX RD EN
|
||||||
|
// [2] FIFO RX TX SEL
|
||||||
|
// [1] FIFO MERGE EN
|
||||||
|
// [0] SPI FIFO RD WR SEL
|
||||||
|
|
||||||
|
#define CMT2300A_CUS_INT_CLR1 0x6A // clear interrupts Bank1
|
||||||
|
#define CMT2300A_CUS_INT_CLR2 0x6B // clear interrupts Bank2
|
||||||
|
#define CMT2300A_CUS_FIFO_CLR 0x6C
|
||||||
|
|
||||||
|
#define CMT2300A_CUS_INT_FLAG 0x6D // [7] LBD FLG
|
||||||
|
// [6] COL ERR FLG
|
||||||
|
// [5] PKT ERR FLG
|
||||||
|
// [4] PREAM OK FLG
|
||||||
|
// [3] SYNC OK FLG
|
||||||
|
// [2] NODE OK FLG
|
||||||
|
// [1] CRC OK FLG
|
||||||
|
// [0] PKT OK FLG
|
||||||
|
|
||||||
|
#define CMT2300A_CUS_RSSI_DBM 0x70
|
||||||
|
|
||||||
|
#define CMT2300A_GO_SWITCH 0x80
|
||||||
|
#define CMT2300A_GO_TX 0x40
|
||||||
|
#define CMT2300A_GO_TFS 0x20
|
||||||
|
#define CMT2300A_GO_SLEEP 0x10
|
||||||
|
#define CMT2300A_GO_RX 0x08
|
||||||
|
#define CMT2300A_GO_RFS 0x04
|
||||||
|
#define CMT2300A_GO_STBY 0x02
|
||||||
|
#define CMT2300A_GO_EEPROM 0x01
|
||||||
|
|
||||||
|
#define CMT2300A_STA_IDLE 0x00
|
||||||
|
#define CMT2300A_STA_SLEEP 0x01
|
||||||
|
#define CMT2300A_STA_STBY 0x02
|
||||||
|
#define CMT2300A_STA_RFS 0x03
|
||||||
|
#define CMT2300A_STA_TFS 0x04
|
||||||
|
#define CMT2300A_STA_RX 0x05
|
||||||
|
#define CMT2300A_STA_TX 0x06
|
||||||
|
#define CMT2300A_STA_EEPROM 0x07
|
||||||
|
#define CMT2300A_STA_ERROR 0x08
|
||||||
|
#define CMT2300A_STA_CAL 0x09
|
||||||
|
|
||||||
|
#define CMT2300A_INT_SEL_TX_DONE 0x0A
|
||||||
|
|
||||||
|
#define CMT2300A_MASK_TX_DONE_FLG 0x08
|
||||||
|
#define CMT2300A_MASK_PKT_OK_FLG 0x01
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
// 0x10 - 0x1f
|
||||||
|
0x00, 0xF4, 0x10, 0xE2, 0x42, 0x20, 0x0C, 0x81,
|
||||||
|
0x42, 0xCF, 0xA7, 0x8C, 0x42, 0xC4, 0x4E, 0x1C,
|
||||||
|
// 0x20 - 0x2f
|
||||||
|
0xA6, 0xC9, 0x20, 0x20, 0xD2, 0x35, 0x0C, 0x0A,
|
||||||
|
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, 0xD6, 0xD5, 0xD4, 0x2D, 0x01, 0x1D, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x60,
|
||||||
|
// 0x50 - 0x5f
|
||||||
|
0xFF, 0x00, 0x00, 0x1F, 0x10, 0x70, 0x4D, 0x06,
|
||||||
|
0x00, 0x07, 0x50, 0x00, 0x8A, 0x18, 0x3F, 0x7F
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {CMT_SUCCESS = 0, CMT_ERR_SWITCH_STATE, CMT_ERR_TX_PENDING, CMT_ERR_REG_VAL};
|
||||||
|
|
||||||
|
template<class SPI>
|
||||||
|
class Cmt2300a {
|
||||||
|
typedef SPI SpiType;
|
||||||
|
public:
|
||||||
|
Cmt2300a() {}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
mSpi.setup();
|
||||||
|
mTxPending = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call as often as possible
|
||||||
|
void loop() {
|
||||||
|
if(mTxPending) {
|
||||||
|
if(CMT2300A_MASK_TX_DONE_FLG != spi3w.readReg(CMT2300A_CUS_INT_CLR1)) {
|
||||||
|
if(cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY))
|
||||||
|
mTxPending = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void swichChannel(bool reset = true, uint8_t start = 0x00, uint8_t end = 0x22) {
|
||||||
|
if(reset)
|
||||||
|
mRxTxCh = start;
|
||||||
|
else if(++mRxTxCh > end)
|
||||||
|
mRxTxCh = start;
|
||||||
|
// 0: 868.00MHz
|
||||||
|
// 1: 868.23MHz
|
||||||
|
// 2: 868.46MHz
|
||||||
|
// 3: 868.72MHz
|
||||||
|
// 4: 868.97MHz
|
||||||
|
mSpi.writeReg(CMT2300A_CUS_FREQ_CHNL, mRxTxCh);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t checkRx(uint8_t buf[], uint8_t len, int8_t *rssi) {
|
||||||
|
if(mTxPending)
|
||||||
|
return CMT_ERR_TX_PENDING;
|
||||||
|
|
||||||
|
mSpi.readReg(CMT2300A_CUS_INT1_CTL);
|
||||||
|
mSpi.writeReg(CMT2300A_CUS_INT1_CTL, CMT2300A_INT_SEL_TX_DONE);
|
||||||
|
|
||||||
|
uint8_t tmp = mSpi.readReg(CMT2300A_CUS_INT_CLR1);
|
||||||
|
if(0x08 == tmp) // first time after TX this reg is 0x08
|
||||||
|
mSpi.writeReg(CMT2300A_CUS_INT_CLR1, 0x04);
|
||||||
|
else
|
||||||
|
mSpi.writeReg(CMT2300A_CUS_INT_CLR1, 0x00);
|
||||||
|
|
||||||
|
if(0x10 == tmp)
|
||||||
|
mSpi.writeReg(CMT2300A_CUS_INT_CLR2, 0x10);
|
||||||
|
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
|
||||||
|
|
||||||
|
mSpi.writeReg(CMT2300A_CUS_FREQ_CHNL, 0x00); // 863.0 MHz
|
||||||
|
|
||||||
|
if(!cmtSwitchStatus(CMT2300A_GO_RX, CMT2300A_STA_RX))
|
||||||
|
return CMT_ERR_SWITCH_STATE;
|
||||||
|
|
||||||
|
uint8_t state = 0x00;
|
||||||
|
uint16_t timeout = 5000;
|
||||||
|
for(uint8_t i = 0; i < 52; i++) {
|
||||||
|
state = mSpi.readReg(CMT2300A_CUS_INT_FLAG);
|
||||||
|
if(0x00 != state)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((state & 0x10) == 0x10) {
|
||||||
|
while(0 == digitalRead(INTR_PIN)) {
|
||||||
|
usleep(10);
|
||||||
|
if(0 == --timeout)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(0 != timeout) {
|
||||||
|
uint16_t timeout2 = 5000;
|
||||||
|
while(0x18 != (state & 0x18)) {
|
||||||
|
state = mSpi.readReg(CMT2300A_CUS_INT_FLAG);
|
||||||
|
if(0 == timeout2--)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(0 != digitalRead(INTR_PIN)) {
|
||||||
|
uint32_t loops = 0;
|
||||||
|
while((state & 0x1b) != 0x1b) {
|
||||||
|
state = mSpi.readReg(CMT2300A_CUS_INT_FLAG);
|
||||||
|
|
||||||
|
if((state & 0x20) == 0x20)
|
||||||
|
return CMT_ERR_REG_VAL;
|
||||||
|
else if((state & 0x40) == 0x40)
|
||||||
|
return CMT_ERR_REG_VAL;
|
||||||
|
if(++loops > 5000)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// receive ok (pream, sync, node, crc)
|
||||||
|
if((state & 0x1b) == 0x1b) {
|
||||||
|
if(!cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY))
|
||||||
|
return CMT_ERR_SWITCH_STATE;
|
||||||
|
|
||||||
|
mSpi.readFifo(buf, len);
|
||||||
|
*rssi = mSpi.readReg(CMT2300A_CUS_RSSI_DBM) - 128;
|
||||||
|
|
||||||
|
if(!cmtSwitchStatus(CMT2300A_GO_SLEEP, CMT2300A_STA_SLEEP))
|
||||||
|
return CMT_ERR_SWITCH_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!cmtSwitchStatus(CMT2300A_GO_STBY, CMT2300A_STA_STBY))
|
||||||
|
return CMT_ERR_SWITCH_STATE;
|
||||||
|
|
||||||
|
return CMT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tx(uint8_t buf[], uint8_t len) {
|
||||||
|
if(mTxPending)
|
||||||
|
return CMT_ERR_TX_PENDING;
|
||||||
|
|
||||||
|
spi3w.writeReg(CMT2300A_CUS_INT1_CTL, CMT2300A_INT_SEL_TX_DONE);
|
||||||
|
|
||||||
|
if(0x00 == spi3w.readReg(CMT2300A_CUS_INT_FLAG)) {
|
||||||
|
// no data received
|
||||||
|
spi3w.readReg(CMT2300A_CUS_INT_CLR1);
|
||||||
|
spi3w.writeReg(CMT2300A_CUS_INT_CLR1, 0x00);
|
||||||
|
spi3w.writeReg(CMT2300A_CUS_INT_CLR2, 0x00);
|
||||||
|
|
||||||
|
//spi3w.readReg(CMT2300A_CUS_FIFO_CTL); // necessary?
|
||||||
|
spi3w.writeReg(CMT2300A_CUS_FIFO_CTL, 0x07);
|
||||||
|
spi3w.writeReg(CMT2300A_CUS_FIFO_CLR, 0x01);
|
||||||
|
|
||||||
|
spi3w.writeReg(0x45, 0x01);
|
||||||
|
spi3w.writeReg(0x46, len); // payload length
|
||||||
|
|
||||||
|
spi3w.writeFifo(buf, len);
|
||||||
|
|
||||||
|
// send only on base frequency: here 863.0 MHz
|
||||||
|
spi3w.writeReg(CMT2300A_CUS_FREQ_CHNL, 0x00);
|
||||||
|
|
||||||
|
if(!cmtSwitchStatus(CMT2300A_GO_TX, CMT2300A_STA_TX))
|
||||||
|
return CMT_ERR_SWITCH_STATE;
|
||||||
|
|
||||||
|
// wait for tx done
|
||||||
|
mTxPending = CMT_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return CMT_ERR_RX_IN_FIFO;
|
||||||
|
|
||||||
|
return CMT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize CMT2300A, returns true on success
|
||||||
|
bool void reset(void) {
|
||||||
|
mSpi.writeReg(0x7f, 0xff); // soft reset
|
||||||
|
delay(30);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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
|
||||||
|
if(CMT2300A_INT_SEL_TX_DONE != mSpi.readReg(CMT2300A_CUS_INT1_CTL))
|
||||||
|
mSpi.writeReg(CMT2300A_CUS_INT1_CTL, CMT2300A_INT_SEL_TX_DONE);
|
||||||
|
|
||||||
|
// select interrupt 2
|
||||||
|
if(0x07 != mSpi.readReg(CMT2300A_CUS_INT2_CTL))
|
||||||
|
mSpi.writeReg(CMT2300A_CUS_INT2_CTL, 0x07);
|
||||||
|
|
||||||
|
// 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))
|
||||||
|
mSpi.writeReg(CMT2300A_CUS_FIFO_CTL, 0x02); // FIFO_MERGE_EN
|
||||||
|
|
||||||
|
if(!cmtSwitchStatus(CMT2300A_GO_SLEEP, CMT2300A_STA_SLEEP))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
delayMicroseconds(95);
|
||||||
|
|
||||||
|
// base frequency 863MHz, with value of CMT2300A_CUS_FREQ_CHNL
|
||||||
|
// the frequency can be increase 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;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// CMT state machine, wait for next state, true on success
|
||||||
|
bool cmtSwitchStatus(uint8_t cmd, uint8_t waitFor, uint16_t cycles = 40) {
|
||||||
|
mSpi.writeReg(CMT2300A_CUS_MODE_CTL, cmd);
|
||||||
|
while(cycles--) {
|
||||||
|
yield();
|
||||||
|
delayMicroseconds(10);
|
||||||
|
if(waitFor == (getChipStatus() & waitFor))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//Serial.println("status wait for: " + String(waitFor, HEX) + " read: " + String(getChipStatus(), HEX));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpiType mSpi;
|
||||||
|
bool mTxPending;
|
||||||
|
uint8_t mRxTxCh;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*__CMT2300A_H__*/
|
138
src/hm/esp32_3wSpi.h
Normal file
138
src/hm/esp32_3wSpi.h
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __ESP32_3WSPI_H__
|
||||||
|
#define __ESP32_3WSPI_H__
|
||||||
|
|
||||||
|
#include "driver/spi_master.h"
|
||||||
|
#include "esp_rom_gpio.h" // for esp_rom_gpio_connect_out_signal
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
#if defined(ESP32)
|
||||||
|
#define CLK_PIN 18
|
||||||
|
#define MOSI_PIN 23
|
||||||
|
#define MISO_PIN -1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SPI_CLK 1 * 1000 * 1000 // 1MHz
|
||||||
|
|
||||||
|
template<uint8_t CSB_PIN=5, uint8_t FCSB_PIN=4, uint8_t GPIO3_PIN=15>
|
||||||
|
class esp32_3wSpi {
|
||||||
|
public:
|
||||||
|
esp32_3wSpi() {}
|
||||||
|
void setup() {
|
||||||
|
spi_bus_config_t buscfg = {
|
||||||
|
.mosi_io_num = MOSI_PIN,
|
||||||
|
.miso_io_num = MISO_PIN,
|
||||||
|
.sclk_io_num = CLK_PIN,
|
||||||
|
.quadwp_io_num = -1,
|
||||||
|
.quadhd_io_num = -1,
|
||||||
|
.max_transfer_sz = 32,
|
||||||
|
};
|
||||||
|
spi_device_interface_config_t devcfg = {
|
||||||
|
.command_bits = 0,
|
||||||
|
.address_bits = 0,
|
||||||
|
.dummy_bits = 0,
|
||||||
|
.mode = 0, // SPI mode 0
|
||||||
|
.clock_speed_hz = SPI_CLK, // 1 MHz
|
||||||
|
.spics_io_num = CS_PIN,
|
||||||
|
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
|
||||||
|
.queue_size = 1,
|
||||||
|
.pre_cb = NULL,
|
||||||
|
.post_cb = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &buscfg, 0));
|
||||||
|
ESP_ERROR_CHECK(spi_bus_add_device(SPI2_HOST, &devcfg, &spi_reg));
|
||||||
|
|
||||||
|
// FiFo
|
||||||
|
spi_device_interface_config_t devcfg2 = {
|
||||||
|
.command_bits = 0,
|
||||||
|
.address_bits = 0,
|
||||||
|
.dummy_bits = 0,
|
||||||
|
.mode = 0, // SPI mode 0
|
||||||
|
.cs_ena_pretrans = 2,
|
||||||
|
.cs_ena_posttrans = (uint8_t)(1 / (SPI_CLK * 10e6 * 2) + 2), // >2 us
|
||||||
|
.clock_speed_hz = SPI_CLK, // 1 MHz
|
||||||
|
.spics_io_num = FCS_PIN,
|
||||||
|
.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE,
|
||||||
|
.queue_size = 1,
|
||||||
|
.pre_cb = NULL,
|
||||||
|
.post_cb = NULL,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(spi_bus_add_device(SPI2_HOST, &devcfg2, &spi_fifo));
|
||||||
|
|
||||||
|
esp_rom_gpio_connect_out_signal(MOSI_PIN, spi_periph_signal[SPI2_HOST].spid_out, true, false);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
pinMode(INTR_PIN, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeReg(uint8_t addr, uint8_t reg) {
|
||||||
|
uint8_t tx_data[2];
|
||||||
|
tx_data[0] = ~addr;
|
||||||
|
tx_data[1] = ~reg;
|
||||||
|
spi_transaction_t t = {
|
||||||
|
.length = 2 * 8,
|
||||||
|
.tx_buffer = &tx_data,
|
||||||
|
.rx_buffer = NULL
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t));
|
||||||
|
delayMicroseconds(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t readReg(uint8_t addr) {
|
||||||
|
uint8_t tx_data, rx_data;
|
||||||
|
tx_data = ~(addr | 0x80); // negation and MSB high (read command)
|
||||||
|
spi_transaction_t t = {
|
||||||
|
.length = 8,
|
||||||
|
.rxlength = 8,
|
||||||
|
.tx_buffer = &tx_data,
|
||||||
|
.rx_buffer = &rx_data
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_reg, &t));
|
||||||
|
delayMicroseconds(100);
|
||||||
|
return rx_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeFifo(uint8_t buf[], uint8_t len) {
|
||||||
|
uint8_t tx_data;
|
||||||
|
|
||||||
|
spi_transaction_t t = {
|
||||||
|
.flags = SPI_TRANS_MODE_OCT,
|
||||||
|
.length = 8,
|
||||||
|
.tx_buffer = &tx_data, // reference to write data
|
||||||
|
.rx_buffer = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < len; i++) {
|
||||||
|
tx_data = ~buf[i]; // negate buffer contents
|
||||||
|
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t));
|
||||||
|
delayMicroseconds(4); // > 4 us
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void readFifo(uint8_t buf[], uint8_t len) {
|
||||||
|
uint8_t rx_data;
|
||||||
|
|
||||||
|
spi_transaction_t t = {
|
||||||
|
.length = 8,
|
||||||
|
.rxlength = 8,
|
||||||
|
.tx_buffer = NULL,
|
||||||
|
.rx_buffer = &rx_data
|
||||||
|
};
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < len; i++) {
|
||||||
|
ESP_ERROR_CHECK(spi_device_polling_transmit(spi_fifo, &t));
|
||||||
|
delayMicroseconds(4); // > 4 us
|
||||||
|
buf[i] = rx_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
spi_device_handle_t spi_reg, spi_fifo;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*__ESP32_3WSPI_H__*/
|
|
@ -307,7 +307,7 @@ class HmPayload {
|
||||||
DPRINT(DBG_INFO, F("Payload ("));
|
DPRINT(DBG_INFO, F("Payload ("));
|
||||||
DBGPRINT(String(payloadLen));
|
DBGPRINT(String(payloadLen));
|
||||||
DBGPRINT(F("): "));
|
DBGPRINT(F("): "));
|
||||||
mSys->Radio.dumpBuf(payload, payloadLen);
|
ah::dumpBuf(payload, payloadLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == rec) {
|
if (NULL == rec) {
|
||||||
|
|
|
@ -188,7 +188,7 @@ class HmRadio {
|
||||||
mTxBuf[cnt++] = ((data[1] ) >> 8) & 0xff; // setting for persistens handlings
|
mTxBuf[cnt++] = ((data[1] ) >> 8) & 0xff; // setting for persistens handlings
|
||||||
mTxBuf[cnt++] = ((data[1] ) ) & 0xff; // setting for persistens handling
|
mTxBuf[cnt++] = ((data[1] ) ) & 0xff; // setting for persistens handling
|
||||||
}
|
}
|
||||||
sendPacket(invId, cnt, isRetransmit, true);
|
sendPacket(invId, cnt, isRetransmit);
|
||||||
}
|
}
|
||||||
|
|
||||||
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(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.
|
||||||
|
@ -201,21 +201,12 @@ class HmRadio {
|
||||||
mTxBuf[18] = (alarmMesId >> 8) & 0xff;
|
mTxBuf[18] = (alarmMesId >> 8) & 0xff;
|
||||||
mTxBuf[19] = (alarmMesId ) & 0xff;
|
mTxBuf[19] = (alarmMesId ) & 0xff;
|
||||||
}
|
}
|
||||||
sendPacket(invId, 24, isRetransmit, true);
|
sendPacket(invId, 24, isRetransmit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool isRetransmit) {
|
void sendCmdPacket(uint64_t invId, uint8_t mid, uint8_t pid, bool isRetransmit) {
|
||||||
initPacket(invId, mid, pid);
|
initPacket(invId, mid, pid);
|
||||||
sendPacket(invId, 10, isRetransmit, false);
|
sendPacket(invId, 10, isRetransmit);
|
||||||
}
|
|
||||||
|
|
||||||
void dumpBuf(uint8_t buf[], uint8_t len) {
|
|
||||||
//DPRINTLN(DBG_VERBOSE, F("hmRadio.h:dumpBuf"));
|
|
||||||
for(uint8_t i = 0; i < len; i++) {
|
|
||||||
DHEX(buf[i]);
|
|
||||||
DBGPRINT(" ");
|
|
||||||
}
|
|
||||||
DBGPRINTLN("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getDataRate(void) {
|
uint8_t getDataRate(void) {
|
||||||
|
@ -279,7 +270,7 @@ class HmRadio {
|
||||||
mTxBuf[9] = pid;
|
mTxBuf[9] = pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendPacket(uint64_t invId, uint8_t len, bool isRetransmit, bool clear=false) {
|
void sendPacket(uint64_t invId, uint8_t len, bool isRetransmit) {
|
||||||
//DPRINTLN(DBG_VERBOSE, F("hmRadio.h:sendPacket"));
|
//DPRINTLN(DBG_VERBOSE, F("hmRadio.h:sendPacket"));
|
||||||
//DPRINTLN(DBG_VERBOSE, "sent packet: #" + String(mSendCnt));
|
//DPRINTLN(DBG_VERBOSE, "sent packet: #" + String(mSendCnt));
|
||||||
|
|
||||||
|
@ -300,7 +291,7 @@ class HmRadio {
|
||||||
DBGPRINT("B Ch");
|
DBGPRINT("B Ch");
|
||||||
DBGPRINT(String(mRfChLst[mTxChIdx]));
|
DBGPRINT(String(mRfChLst[mTxChIdx]));
|
||||||
DBGPRINT(F(" | "));
|
DBGPRINT(F(" | "));
|
||||||
dumpBuf(mTxBuf, len);
|
ah::dumpBuf(mTxBuf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
mNrf24.stopListening();
|
mNrf24.stopListening();
|
||||||
|
|
191
src/hm/hmsRadio.h
Normal file
191
src/hm/hmsRadio.h
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 2023 Ahoy, https://github.com/lumpapu/ahoy
|
||||||
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __HMS_RADIO_H__
|
||||||
|
#define __HMS_RADIO_H__
|
||||||
|
|
||||||
|
#include "../utils/dbg.h"
|
||||||
|
#include "cmt2300a.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int8_t rssi;
|
||||||
|
uint8_t data[28];
|
||||||
|
} hmsPacket_t;
|
||||||
|
|
||||||
|
#define U32_B3(val) ((uint8_t)((val >> 24) & 0xff))
|
||||||
|
#define U32_B2(val) ((uint8_t)((val >> 16) & 0xff))
|
||||||
|
#define U32_B1(val) ((uint8_t)((val >> 8) & 0xff))
|
||||||
|
#define U32_B0(val) ((uint8_t)((val ) & 0xff))
|
||||||
|
|
||||||
|
template<class SPI, uint32_t DTU_SN = 0x87654321>
|
||||||
|
class HmsRadio {
|
||||||
|
typedef SPI SpiType;
|
||||||
|
typedef Cmt2300a<SpiType> CmtType;
|
||||||
|
public:
|
||||||
|
HmsRadio() {
|
||||||
|
mDtuSn = DTU_SN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup(bool genDtuSn = true) {
|
||||||
|
if(genDtuSn)
|
||||||
|
generateDtuSn();
|
||||||
|
if(!mCmt.resetCMT())
|
||||||
|
DPRINTLN(DBG_WARN, F("Initializing CMT2300A failed!"));
|
||||||
|
|
||||||
|
mSendCnt = 0;
|
||||||
|
mRetransmits = 0
|
||||||
|
mSerialDebug = false;
|
||||||
|
mIvIdChannelSet = NULL;
|
||||||
|
mIrqRcvd = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
mCmt.loop();
|
||||||
|
if(!mIrqRcvd)
|
||||||
|
return;
|
||||||
|
mIrqRcvd = false;
|
||||||
|
getRx();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tickSecond() {
|
||||||
|
if(NULL != mIvIdChannelSet)
|
||||||
|
prepareSwitchFreqCmd(mIvIdChannelSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handeIntr(void) {
|
||||||
|
mIrqRcvd = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enableDebug() {
|
||||||
|
mSerialDebug = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setIvBackChannel(const uint32_t *ivId) {
|
||||||
|
mIvIdChannelSet = ivId;
|
||||||
|
prepareSwitchFreqCmd();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareDevInformCmd(const uint32_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.
|
||||||
|
initPacket(ivId, reqfld, ALL_FRAMES);
|
||||||
|
mTxBuf[10] = cmd;
|
||||||
|
mTxBuf[12] = U32_B3(ts);
|
||||||
|
mTxBuf[13] = U32_B2(ts);
|
||||||
|
mTxBuf[14] = U32_B1(ts);
|
||||||
|
mTxBuf[15] = U32_B0(ts);
|
||||||
|
/*if (cmd == RealTimeRunData_Debug || cmd == AlarmData ) {
|
||||||
|
mTxBuf[18] = (alarmMesId >> 8) & 0xff;
|
||||||
|
mTxBuf[19] = (alarmMesId ) & 0xff;
|
||||||
|
}*/
|
||||||
|
mCmt.swichChannel(true);
|
||||||
|
sendPacket(24, isRetransmit);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void prepareSwitchChannelCmd(const uint32_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;
|
||||||
|
mCmt.swichChannel();
|
||||||
|
sendPacket(14, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendPacket(uint8_t len, bool isRetransmit) {
|
||||||
|
if (len > 14) {
|
||||||
|
uint16_t crc = ah::crc16(&mTxBuf[10], len - 10);
|
||||||
|
mTxBuf[len++] = (crc >> 8) & 0xff;
|
||||||
|
mTxBuf[len++] = (crc ) & 0xff;
|
||||||
|
}
|
||||||
|
mTxBuf[len] = ah::crc8(mTxBuf, len);
|
||||||
|
len++;
|
||||||
|
|
||||||
|
if(mSerialDebug) {
|
||||||
|
DPRINT(DBG_INFO, F("TX "));
|
||||||
|
DBGPRINT(String(len));
|
||||||
|
DBGPRINT("B Ch");
|
||||||
|
DBGPRINT(String(mRfChLst[mTxChIdx]));
|
||||||
|
DBGPRINT(F(" | "));
|
||||||
|
ah::dumpBuf(mTxBuf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t status = mCmt.tx(mTxBuf, len);
|
||||||
|
if(CMT_SUCCESS != status) {
|
||||||
|
DPRINT(DBG_WARN, F("CMT TX failed, code: "));
|
||||||
|
DBGPRINTLN(String(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isRetransmit)
|
||||||
|
mRetransmits++;
|
||||||
|
else
|
||||||
|
mSendCnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mSendCnt;
|
||||||
|
uint32_t mRetransmits;
|
||||||
|
std::queue<hmsPacket_t> mBufCtrl;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initPacket(const uint32_t *ivId, uint8_t mid, uint8_t pid) {
|
||||||
|
mTxBuf[0] = mid;
|
||||||
|
mTxBuf[1] = U32_B3(*ivId);
|
||||||
|
mTxBuf[2] = U32_B2(*ivId);
|
||||||
|
mTxBuf[3] = U32_B1(*ivId);
|
||||||
|
mTxBuf[4] = U32_B0(*ivId);
|
||||||
|
mTxBuf[5] = U32_B3(mDtuSn);
|
||||||
|
mTxBuf[6] = U32_B2(mDtuSn);
|
||||||
|
mTxBuf[7] = U32_B1(mDtuSn);
|
||||||
|
mTxBuf[8] = U32_B0(mDtuSn);
|
||||||
|
mTxBuf[9] = pid;
|
||||||
|
memset(&mTxBuf[10], 0x00, 17);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void generateDtuSn(void) {
|
||||||
|
uint32_t chipID = 0;
|
||||||
|
#ifdef ESP32
|
||||||
|
uint64_t MAC = ESP.getEfuseMac();
|
||||||
|
chipID = ((MAC >> 8) & 0xFF0000) | ((MAC >> 24) & 0xFF00) | ((MAC >> 40) & 0xFF);
|
||||||
|
#endif
|
||||||
|
dtuSn = 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++) {
|
||||||
|
dtuSn |= (chipID % 10) << (i * 4);
|
||||||
|
chipID /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void getRx(void) {
|
||||||
|
hmsPacket_t p;
|
||||||
|
uint8_t status = mCmt.checkRx(p.data, 28, &p.rssi);
|
||||||
|
if(CMT_SUCCESS == status)
|
||||||
|
mBufCtrl.push(p);
|
||||||
|
if(NULL != mIvIdChannelSet) {
|
||||||
|
if(U32_B3(*mIvIdChannelSet) != p.data[2])
|
||||||
|
return;
|
||||||
|
if(U32_B2(*mIvIdChannelSet) != p.data[3])
|
||||||
|
return;
|
||||||
|
if(U32_B1(*mIvIdChannelSet) != p.data[4])
|
||||||
|
return;
|
||||||
|
if(U32_B0(*mIvIdChannelSet) != p.data[5])
|
||||||
|
return;
|
||||||
|
*mIvIdChannelSet = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CmtType mCmt;
|
||||||
|
uint32_t mDtuSn;
|
||||||
|
uint8_t[27] mTxBuf;
|
||||||
|
bool mSerialDebug;
|
||||||
|
uint32_t *mIvIdChannelSet;
|
||||||
|
bool mIrqRcvd;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /*__HMS_RADIO_H__*/
|
|
@ -194,7 +194,7 @@ class MiPayload {
|
||||||
|
|
||||||
if (mSerialDebug) {
|
if (mSerialDebug) {
|
||||||
DPRINT(DBG_INFO, F("Payload (") + String(payloadLen) + "): ");
|
DPRINT(DBG_INFO, F("Payload (") + String(payloadLen) + "): ");
|
||||||
mSys->Radio.dumpBuf(payload, payloadLen);
|
ah::dumpBuf(payload, payloadLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == rec) {
|
if (NULL == rec) {
|
||||||
|
|
|
@ -15,13 +15,18 @@ IRAM_ATTR void handleIntr(void) {
|
||||||
myApp.handleIntr();
|
myApp.handleIntr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
IRAM_ATTR void handleHmsIntr(void) {
|
||||||
|
myApp.handleHmsIntr();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void setup() {
|
void setup() {
|
||||||
myApp.setup();
|
myApp.setup();
|
||||||
|
|
||||||
// TODO: move to HmRadio
|
|
||||||
attachInterrupt(digitalPinToInterrupt(myApp.getIrqPin()), handleIntr, FALLING);
|
attachInterrupt(digitalPinToInterrupt(myApp.getIrqPin()), handleIntr, FALLING);
|
||||||
|
attachInterrupt(digitalPinToInterrupt(myApp.getHmsIrqPin()), handleHmsIntr, RISING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
#include "dbg.h"
|
||||||
|
|
||||||
namespace ah {
|
namespace ah {
|
||||||
void ip2Arr(uint8_t ip[], const char *ipStr) {
|
void ip2Arr(uint8_t ip[], const char *ipStr) {
|
||||||
|
@ -64,4 +65,12 @@ namespace ah {
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dumpBuf(uint8_t buf[], uint8_t len) {
|
||||||
|
for(uint8_t i = 0; i < len; i++) {
|
||||||
|
DHEX(buf[i]);
|
||||||
|
DBGPRINT(" ");
|
||||||
|
}
|
||||||
|
DBGPRINTLN("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// 2022 Ahoy, https://ahoydtu.de
|
// 2023 Ahoy, https://ahoydtu.de
|
||||||
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ namespace ah {
|
||||||
String getDateTimeStr(time_t t);
|
String getDateTimeStr(time_t t);
|
||||||
String getTimeStr(time_t t);
|
String getTimeStr(time_t t);
|
||||||
uint64_t Serial2u64(const char *val);
|
uint64_t Serial2u64(const char *val);
|
||||||
|
void dumpBuf(uint8_t buf[], uint8_t len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /*__HELPER_H__*/
|
#endif /*__HELPER_H__*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue