First implementation of TX queue

This is required to implement some features of e.g. MI Inverters or to read the event log of HM inverters
This commit is contained in:
Thomas Basler 2022-06-27 19:09:52 +02:00
parent 8420848fac
commit 7a0394151a
3 changed files with 29 additions and 5 deletions

View File

@ -114,6 +114,13 @@ void HoymilesRadio::loop()
_busyFlag = false; _busyFlag = false;
} }
} }
} else if (!_busyFlag) {
// Currently in idle mode --> send packet if one is in the queue
if (!_txBuffer.empty()) {
inverter_transaction_t* t = _txBuffer.getBack();
sendEsbPacket(t->target, t->mainCmd, t->subCmd, t->payload, t->len, t->timeout);
_txBuffer.popBack();
}
} }
} }
@ -246,19 +253,31 @@ void HoymilesRadio::sendEsbPacket(serial_u target, uint8_t mainCmd, uint8_t subC
openReadingPipe(); openReadingPipe();
_radio->setChannel(getRxNxtChannel()); _radio->setChannel(getRxNxtChannel());
_radio->startListening(); _radio->startListening();
_activeSerial = target;
_busyFlag = true; _busyFlag = true;
_rxTimeout.set(timeout); _rxTimeout.set(timeout);
} }
bool HoymilesRadio::enqueTransaction(inverter_transaction_t* transaction)
{
if (!_txBuffer.full()) {
inverter_transaction_t* t;
t = _txBuffer.getFront();
memcpy(t, transaction, sizeof(inverter_transaction_t));
_txBuffer.pushFront(t);
return true;
} else {
Serial.println(F("TX Buffer full"));
}
return false;
}
void HoymilesRadio::sendTimePacket(std::shared_ptr<InverterAbstract> iv) void HoymilesRadio::sendTimePacket(std::shared_ptr<InverterAbstract> iv)
{ {
inverter_transaction_t payload; inverter_transaction_t payload;
if (iv->getStatsRequest(&payload)) { if (iv->getStatsRequest(&payload)) {
serial_u s; enqueTransaction(&payload);
s.u64 = iv->serial();
_activeSerial.u64 = iv->serial();
sendEsbPacket(s, payload.mainCmd, payload.subCmd, payload.payload, payload.len, payload.timeout);
} }
} }

View File

@ -11,6 +11,8 @@
// number of fragments hold in buffer // number of fragments hold in buffer
#define FRAGMENT_BUFFER_SIZE 30 #define FRAGMENT_BUFFER_SIZE 30
#define TX_BUFFER_SIZE 5
#define MAX_RESEND_COUNT 3 #define MAX_RESEND_COUNT 3
class HoymilesRadio { class HoymilesRadio {
@ -27,6 +29,7 @@ public:
void sendTimePacket(std::shared_ptr<InverterAbstract> iv); void sendTimePacket(std::shared_ptr<InverterAbstract> iv);
void sendRetransmitPacket(uint8_t fragment_id); void sendRetransmitPacket(uint8_t fragment_id);
void sendLastPacketAgain(); void sendLastPacketAgain();
bool enqueTransaction(inverter_transaction_t* transaction);
static void u32CpyLittleEndian(uint8_t dest[], uint32_t src); static void u32CpyLittleEndian(uint8_t dest[], uint32_t src);
@ -60,4 +63,5 @@ private:
bool _busyFlag = false; bool _busyFlag = false;
inverter_transaction_t currentTransaction; inverter_transaction_t currentTransaction;
CircularBuffer<inverter_transaction_t, TX_BUFFER_SIZE> _txBuffer;
}; };

View File

@ -12,6 +12,7 @@ bool HM_Abstract::getStatsRequest(inverter_transaction_t* payload)
memset(payload->payload, 0, MAX_RF_PAYLOAD_SIZE); memset(payload->payload, 0, MAX_RF_PAYLOAD_SIZE);
payload->target.u64 = serial();
payload->mainCmd = 0x15; payload->mainCmd = 0x15;
payload->subCmd = 0x80; payload->subCmd = 0x80;
payload->timeout = 200; payload->timeout = 200;