Remove cmtProocess method and move RF logic into the cmt2300wrapper class
This commit is contained in:
parent
f5767e61ef
commit
e2aa29f117
@ -25,6 +25,46 @@ bool CMT2300A::isChipConnected()
|
|||||||
return CMT2300A_IsExist();
|
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)
|
bool CMT2300A::write(const uint8_t* buf, uint8_t len)
|
||||||
{
|
{
|
||||||
CMT2300A_GoStby();
|
CMT2300A_GoStby();
|
||||||
@ -70,6 +110,18 @@ uint8_t CMT2300A::getChannel(void)
|
|||||||
return CMT2300A_ReadReg(CMT2300A_CUS_FREQ_CHNL);
|
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)
|
bool CMT2300A::setPALevel(int8_t level)
|
||||||
{
|
{
|
||||||
uint16_t Tx_dBm_word;
|
uint16_t Tx_dBm_word;
|
||||||
@ -183,6 +235,18 @@ bool CMT2300A::setPALevel(int8_t level)
|
|||||||
return true;
|
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()
|
bool CMT2300A::_init_pins()
|
||||||
{
|
{
|
||||||
CMT2300A_InitSpi(_pin_sdio, _pin_clk, _pin_cs, _pin_fcs, _spi_speed);
|
CMT2300A_InitSpi(_pin_sdio, _pin_clk, _pin_cs, _pin_fcs, _spi_speed);
|
||||||
|
|||||||
@ -19,6 +19,43 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isChipConnected();
|
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);
|
bool write(const uint8_t* buf, uint8_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,8 +70,27 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint8_t getChannel(void);
|
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 setPALevel(int8_t level);
|
||||||
|
|
||||||
|
bool rxFifoAvailable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empty the RX (receive) FIFO buffers.
|
||||||
|
*/
|
||||||
|
void flush_rx(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* initialize the GPIO pins
|
* initialize the GPIO pins
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
#include "Hoymiles.h"
|
#include "Hoymiles.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include <FunctionalInterrupt.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_BOOT_FREQ 868000000 // Hoymiles boot/init frequency after power up inverter or connection lost for 15 min
|
||||||
#define HOY_BASE_FREQ 860000000
|
#define HOY_BASE_FREQ 860000000
|
||||||
@ -54,128 +53,6 @@ bool HoymilesRadio_CMT::cmtSwitchDtuFreq(const uint32_t to_freq_kHz)
|
|||||||
return true;
|
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)
|
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;
|
_dtuSerial.u64 = 0;
|
||||||
@ -210,9 +87,37 @@ void HoymilesRadio_CMT::loop()
|
|||||||
if (!_isInitialized) {
|
if (!_isInitialized) {
|
||||||
return;
|
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()) {
|
if (!_rxBuffer.empty()) {
|
||||||
fragment_t f = _rxBuffer.back();
|
fragment_t f = _rxBuffer.back();
|
||||||
if (checkFragmentCrc(&f)) {
|
if (checkFragmentCrc(&f)) {
|
||||||
@ -360,6 +265,8 @@ void HoymilesRadio_CMT::sendEsbPacket(CommandAbstract* cmd)
|
|||||||
|
|
||||||
cmd->setRouterAddress(DtuSerial().u64);
|
cmd->setRouterAddress(DtuSerial().u64);
|
||||||
|
|
||||||
|
_radio->stopListening();
|
||||||
|
|
||||||
uint8_t oldChannel;
|
uint8_t oldChannel;
|
||||||
oldChannel = _radio->getChannel();
|
oldChannel = _radio->getChannel();
|
||||||
if (cmd->getDataPayload()[0] == 0x56) { // @todo(tbnobody) Bad hack to identify ChannelChange Command
|
if (cmd->getDataPayload()[0] == 0x56) { // @todo(tbnobody) Bad hack to identify ChannelChange Command
|
||||||
@ -370,13 +277,11 @@ void HoymilesRadio_CMT::sendEsbPacket(CommandAbstract* cmd)
|
|||||||
cmd->getCommandName().c_str(), getFrequencyFromChannel(_radio->getChannel()));
|
cmd->getCommandName().c_str(), getFrequencyFromChannel(_radio->getChannel()));
|
||||||
cmd->dumpDataPayload(Hoymiles.getMessageOutput());
|
cmd->dumpDataPayload(Hoymiles.getMessageOutput());
|
||||||
|
|
||||||
if (_radio->write(cmd->getDataPayload(), cmd->getDataSize())) {
|
if (!_radio->write(cmd->getDataPayload(), cmd->getDataSize())) {
|
||||||
cmtNextState = CMT_STATE_RX_START;
|
|
||||||
} else {
|
|
||||||
Hoymiles.getMessageOutput()->println("TX SPI Timeout");
|
Hoymiles.getMessageOutput()->println("TX SPI Timeout");
|
||||||
}
|
}
|
||||||
_radio->setChannel(oldChannel);
|
_radio->setChannel(oldChannel);
|
||||||
|
_radio->startListening();
|
||||||
_busyFlag = true;
|
_busyFlag = true;
|
||||||
_rxTimeout.set(cmd->getTimeout());
|
_rxTimeout.set(cmd->getTimeout());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,9 +6,9 @@
|
|||||||
#include "commands/CommandAbstract.h"
|
#include "commands/CommandAbstract.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <cmt2300wrapper.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <cmt2300wrapper.h>
|
|
||||||
|
|
||||||
// number of fragments hold in buffer
|
// number of fragments hold in buffer
|
||||||
#define FRAGMENT_BUFFER_SIZE 30
|
#define FRAGMENT_BUFFER_SIZE 30
|
||||||
@ -17,25 +17,6 @@
|
|||||||
#define HOYMILES_CMT_WORK_FREQ 865000
|
#define HOYMILES_CMT_WORK_FREQ 865000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* CMT states */
|
|
||||||
typedef enum {
|
|
||||||
CMT_STATE_IDLE = 0,
|
|
||||||
CMT_STATE_RX_START,
|
|
||||||
CMT_STATE_RX_WAIT,
|
|
||||||
CMT_STATE_RX_DONE,
|
|
||||||
CMT_STATE_RX_TIMEOUT,
|
|
||||||
CMT_STATE_ERROR,
|
|
||||||
} enumCMTstate;
|
|
||||||
|
|
||||||
/* CMT process function results */
|
|
||||||
typedef enum {
|
|
||||||
CMT_IDLE = 0,
|
|
||||||
CMT_BUSY,
|
|
||||||
CMT_RX_DONE,
|
|
||||||
CMT_RX_TIMEOUT,
|
|
||||||
CMT_ERROR,
|
|
||||||
} enumCMTresult;
|
|
||||||
|
|
||||||
class HoymilesRadio_CMT : public HoymilesRadio {
|
class HoymilesRadio_CMT : public HoymilesRadio {
|
||||||
public:
|
public:
|
||||||
void 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);
|
void 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);
|
||||||
@ -73,10 +54,4 @@ private:
|
|||||||
uint32_t _inverterTargetFrequency = HOYMILES_CMT_WORK_FREQ;
|
uint32_t _inverterTargetFrequency = HOYMILES_CMT_WORK_FREQ;
|
||||||
|
|
||||||
bool cmtSwitchDtuFreq(const uint32_t to_freq_kHz);
|
bool cmtSwitchDtuFreq(const uint32_t to_freq_kHz);
|
||||||
enumCMTresult cmtProcess(void);
|
|
||||||
|
|
||||||
enumCMTstate cmtNextState = CMT_STATE_IDLE;
|
|
||||||
|
|
||||||
uint32_t cmtRxTimeout = 200;
|
|
||||||
uint32_t cmtRxTimeCount = 0;
|
|
||||||
};
|
};
|
||||||
Loading…
Reference in New Issue
Block a user