Skip to content

Commit

Permalink
Remove cmtProocess method and move RF logic into the cmt2300wrapper c…
Browse files Browse the repository at this point in the history
…lass
  • Loading branch information
tbnobody committed Apr 15, 2023
1 parent f5767e6 commit e2aa29f
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 155 deletions.
64 changes: 64 additions & 0 deletions lib/CMT2300a/cmt2300wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,46 @@ bool CMT2300A::isChipConnected()
return CMT2300A_IsExist();
}

bool CMT2300A::startListening(void)
{
CMT2300A_GoStby();
CMT2300A_ClearInterruptFlags();

/* Must clear FIFO after enable SPI to read or write the FIFO */
CMT2300A_EnableReadFifo();
CMT2300A_ClearRxFifo();

if (!CMT2300A_GoRx()) {
return false;
} else {
return true;
}
}

bool CMT2300A::stopListening(void)
{
CMT2300A_ClearInterruptFlags();
return CMT2300A_GoSleep();
}

bool CMT2300A::available(void)
{
return (
CMT2300A_MASK_PREAM_OK_FLG |
CMT2300A_MASK_SYNC_OK_FLG |
CMT2300A_MASK_CRC_OK_FLG |
CMT2300A_MASK_PKT_OK_FLG
) & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG);
}

void CMT2300A::read(void* buf, uint8_t len)
{
// Fetch the payload
CMT2300A_ReadFifo(static_cast<uint8_t*>(buf), len);

CMT2300A_ClearInterruptFlags();
}

bool CMT2300A::write(const uint8_t* buf, uint8_t len)
{
CMT2300A_GoStby();
Expand Down Expand Up @@ -70,6 +110,18 @@ uint8_t CMT2300A::getChannel(void)
return CMT2300A_ReadReg(CMT2300A_CUS_FREQ_CHNL);
}

uint8_t CMT2300A::getDynamicPayloadSize(void)
{
uint8_t result;
CMT2300A_ReadFifo(&result, 1); // first byte in FiFo is length
return result;
}

int CMT2300A::getRssiDBm()
{
return CMT2300A_GetRssiDBm();
}

bool CMT2300A::setPALevel(int8_t level)
{
uint16_t Tx_dBm_word;
Expand Down Expand Up @@ -183,6 +235,18 @@ bool CMT2300A::setPALevel(int8_t level)
return true;
}

bool CMT2300A::rxFifoAvailable()
{
return (
CMT2300A_MASK_PKT_OK_FLG
) & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG);
}

void CMT2300A::flush_rx(void)
{
CMT2300A_ClearRxFifo();
}

bool CMT2300A::_init_pins()
{
CMT2300A_InitSpi(_pin_sdio, _pin_clk, _pin_cs, _pin_fcs, _spi_speed);
Expand Down
56 changes: 56 additions & 0 deletions lib/CMT2300a/cmt2300wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,43 @@ class CMT2300A {
*/
bool isChipConnected();

bool startListening(void);

bool stopListening(void);

/**
* Check whether there are bytes available to be read
* @code
* if(radio.available()){
* radio.read(&data,sizeof(data));
* }
* @endcode
*
* @see available(uint8_t*)
*
* @return True if there is a payload available, false if none is
*/
bool available(void);

/**
* Read payload data from the RX FIFO buffer(s).
*
* The length of data read is usually the next available payload's length
* @see
* - getDynamicPayloadSize()
*
* @note I specifically chose `void*` as a data type to make it easier
* for beginners to use. No casting needed.
*
* @param buf Pointer to a buffer where the data should be written
* @param len Maximum number of bytes to read into the buffer. This
* value should match the length of the object referenced using the
* `buf` parameter. The absolute maximum number of bytes that can be read
* in one call is 32 (for dynamic payload lengths) or whatever number was
* previously passed to setPayloadSize() (for static payload lengths).
*/
void read(void* buf, uint8_t len);

bool write(const uint8_t* buf, uint8_t len);

/**
Expand All @@ -33,8 +70,27 @@ class CMT2300A {
*/
uint8_t getChannel(void);

/**
* Get Dynamic Payload Size
*
* For dynamic payloads, this pulls the size of the payload off
* the chip
*
* @return Payload length of last-received dynamic payload
*/
uint8_t getDynamicPayloadSize(void);

int getRssiDBm();

bool setPALevel(int8_t level);

bool rxFifoAvailable();

/**
* Empty the RX (receive) FIFO buffers.
*/
void flush_rx(void);

private:
/**
* initialize the GPIO pins
Expand Down
163 changes: 34 additions & 129 deletions lib/Hoymiles/src/HoymilesRadio_CMT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include "Hoymiles.h"
#include "crc.h"
#include <FunctionalInterrupt.h>
#include <cmt2300a.h>

#define HOY_BOOT_FREQ 868000000 // Hoymiles boot/init frequency after power up inverter or connection lost for 15 min
#define HOY_BASE_FREQ 860000000
Expand Down Expand Up @@ -54,128 +53,6 @@ bool HoymilesRadio_CMT::cmtSwitchDtuFreq(const uint32_t to_freq_kHz)
return true;
}

enumCMTresult HoymilesRadio_CMT::cmtProcess(void)
{
enumCMTresult nRes = CMT_BUSY;

switch (cmtNextState) {
case CMT_STATE_IDLE:
nRes = CMT_IDLE;
break;

case CMT_STATE_RX_START:
CMT2300A_GoStby();
CMT2300A_ClearInterruptFlags();

/* Must clear FIFO after enable SPI to read or write the FIFO */
CMT2300A_EnableReadFifo();
CMT2300A_ClearRxFifo();

if (!CMT2300A_GoRx()) {
cmtNextState = CMT_STATE_ERROR;
} else {
cmtNextState = CMT_STATE_RX_WAIT;
}

cmtRxTimeCount = CMT2300A_GetTickCount();
cmtRxTimeout = 200;

break;

case CMT_STATE_RX_WAIT:
if (!_gpio3_configured) {
if (CMT2300A_MASK_PKT_OK_FLG & CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG)) { // read INT2, PKT_OK flag
_packetReceived = true;
}
}

if (_packetReceived)
{
Hoymiles.getMessageOutput()->println("Interrupt 2 received");
_packetReceived = false; // reset interrupt 2
cmtNextState = CMT_STATE_RX_DONE;
}

if ((CMT2300A_GetTickCount() - cmtRxTimeCount) > cmtRxTimeout) {
cmtNextState = CMT_STATE_RX_TIMEOUT;
}

break;

case CMT_STATE_RX_DONE: {
CMT2300A_GoStby();

bool isLastFrame = false;

uint8_t state = CMT2300A_ReadReg(CMT2300A_CUS_INT_FLAG);
if ((state & 0x1b) == 0x1b) {

if (!(_rxBuffer.size() > FRAGMENT_BUFFER_SIZE)) {
fragment_t f;
memset(f.fragment, 0xcc, MAX_RF_PAYLOAD_SIZE);
CMT2300A_ReadFifo(&f.len, 1); // first byte in FiFo is length
f.channel = _radio->getChannel();
f.rssi = CMT2300A_GetRssiDBm();
if (f.len > MAX_RF_PAYLOAD_SIZE) {
f.len = MAX_RF_PAYLOAD_SIZE;
}
CMT2300A_ReadFifo(f.fragment, f.len);
if (f.fragment[9] & 0x80) { // last frame detection for end Rx
isLastFrame = true;
}
_rxBuffer.push(f);
} else {
Hoymiles.getMessageOutput()->println("Buffer full");
}
} else if ((state & 0x19) == 0x19) {
Hoymiles.getMessageOutput()->printf("[CMT_STATE_RX_DONE] state: %x (CRC_ERROR)\r\n", state);
} else {
Hoymiles.getMessageOutput()->printf("[CMT_STATE_RX_DONE] wrong state: %x\r\n", state);
}

CMT2300A_ClearInterruptFlags();

CMT2300A_GoSleep();

if (isLastFrame) { // last frame received
cmtNextState = CMT_STATE_IDLE;
} else {
cmtNextState = CMT_STATE_RX_START; // receive next frame(s)
}

nRes = CMT_RX_DONE;
break;
}

case CMT_STATE_RX_TIMEOUT:
CMT2300A_GoSleep();

Hoymiles.getMessageOutput()->println("RX timeout!");

cmtNextState = CMT_STATE_IDLE;

nRes = CMT_RX_TIMEOUT;
break;

case CMT_STATE_ERROR:
CMT2300A_SoftReset();
CMT2300A_DelayMs(20);

CMT2300A_GoStby();
_radio->begin();

cmtNextState = CMT_STATE_IDLE;

nRes = CMT_ERROR;
break;

default:
break;
}

return nRes;
}

void HoymilesRadio_CMT::init(int8_t pin_sdio, int8_t pin_clk, int8_t pin_cs, int8_t pin_fcs, int8_t pin_gpio2, int8_t pin_gpio3)
{
_dtuSerial.u64 = 0;
Expand Down Expand Up @@ -210,9 +87,37 @@ void HoymilesRadio_CMT::loop()
if (!_isInitialized) {
return;
}
enumCMTresult mCMTstate = cmtProcess();

if (mCMTstate != CMT_RX_DONE) { // Perform package parsing only if no packages are received
if (!_gpio3_configured) {
if (_radio->rxFifoAvailable()) { // read INT2, PKT_OK flag
_packetReceived = true;
}
}

if (_packetReceived) {
Hoymiles.getMessageOutput()->println("Interrupt received");
while (_radio->available()) {
if (!(_rxBuffer.size() > FRAGMENT_BUFFER_SIZE)) {
fragment_t f;
memset(f.fragment, 0xcc, MAX_RF_PAYLOAD_SIZE);
f.len = _radio->getDynamicPayloadSize();
f.channel = _radio->getChannel();
f.rssi = _radio->getRssiDBm();
if (f.len > MAX_RF_PAYLOAD_SIZE) {
f.len = MAX_RF_PAYLOAD_SIZE;
}
_radio->read(f.fragment, f.len);
_rxBuffer.push(f);
} else {
Hoymiles.getMessageOutput()->println("Buffer full");
_radio->flush_rx();
}
}
_radio->flush_rx();
_packetReceived = false;

} else {
// Perform package parsing only if no packages are received
if (!_rxBuffer.empty()) {
fragment_t f = _rxBuffer.back();
if (checkFragmentCrc(&f)) {
Expand Down Expand Up @@ -360,6 +265,8 @@ void HoymilesRadio_CMT::sendEsbPacket(CommandAbstract* cmd)

cmd->setRouterAddress(DtuSerial().u64);

_radio->stopListening();

uint8_t oldChannel;
oldChannel = _radio->getChannel();
if (cmd->getDataPayload()[0] == 0x56) { // @todo(tbnobody) Bad hack to identify ChannelChange Command
Expand All @@ -370,13 +277,11 @@ void HoymilesRadio_CMT::sendEsbPacket(CommandAbstract* cmd)
cmd->getCommandName().c_str(), getFrequencyFromChannel(_radio->getChannel()));
cmd->dumpDataPayload(Hoymiles.getMessageOutput());

if (_radio->write(cmd->getDataPayload(), cmd->getDataSize())) {
cmtNextState = CMT_STATE_RX_START;
} else {
if (!_radio->write(cmd->getDataPayload(), cmd->getDataSize())) {
Hoymiles.getMessageOutput()->println("TX SPI Timeout");
}
_radio->setChannel(oldChannel);

_radio->startListening();
_busyFlag = true;
_rxTimeout.set(cmd->getTimeout());
}
Loading

0 comments on commit e2aa29f

Please sign in to comment.