fix: keep a repeater frame until the radio queue takes it

The frame was popped before queueTx(), so whenever the radio queue was busy
it was lost.  Peek it instead, only remove it once it is queued (or TX is
suspended), and don't try while the queue has no room.  The repeater buffer
moves to TxBuffer.h/.cpp so it can be unit tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-12 18:31:39 +02:00
parent e1c76bc2af
commit 7e9687c023
6 changed files with 227 additions and 80 deletions

View file

@ -22,6 +22,7 @@
#include "SomfyFrame.h"
#include "TxBuffer.h"
enum class group_types : byte {
channel = 0x00
};
@ -54,7 +55,6 @@ enum class tilt_types : byte {
#define MAX_TIMINGS 300
#define MAX_RX_BUFFER 3
#define MAX_TX_BUFFER 5
typedef enum {
waiting_synchro = 0,
@ -95,33 +95,6 @@ struct somfy_rx_queue_t {
void push(somfy_rx_t *rx);
bool pop(somfy_rx_t *rx);
};
struct somfy_tx_t {
void clear() {
this->hwsync = 0;
this->bit_length = 0;
memset(this->payload, 0x00, sizeof(this->payload));
}
uint8_t hwsync = 0;
uint8_t bit_length = 0;
uint8_t payload[10] = {};
};
struct somfy_tx_queue_t {
somfy_tx_queue_t() { this->clear(); }
void clear() {
for (uint8_t i = 0; i < MAX_TX_BUFFER; i++) {
this->index[i] = 255;
this->items[i].clear();
}
this->length = 0;
}
unsigned long delay_time = 0;
uint8_t length = 0;
uint8_t index[MAX_TX_BUFFER] = {255};
somfy_tx_t items[MAX_TX_BUFFER];
bool pop(somfy_tx_t *tx);
void push(somfy_rx_t *rx); // Used for repeats
void push(uint8_t hwsync, byte *payload, uint8_t bit_length);
};
enum class somfy_flags_t : byte {
SunFlag = 0x01,