mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 13:52:15 +01:00
Move the pieces of the radio TX path that don't need FreeRTOS or NVS out of Somfy.cpp and Web.cpp so they build in the native test env: the TX job and event types and job encoding (TxBuffer), the queue rules (TxQueuePolicy.h), a shade's pending radio jobs (ShadeTxState), the next rolling code (RollingCode.h) and the web command queue types (WebCommand.h). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
78 lines
2.7 KiB
C++
78 lines
2.7 KiB
C++
#include "TxBuffer.h"
|
|
#include "esp_log.h"
|
|
|
|
// Logged as part of the radio code it came from.
|
|
static const char *TAG = "Somfy";
|
|
|
|
int8_t somfy_tx_queue_t::oldest() const {
|
|
// The newest index is at position 0 so the oldest is the last one in use.
|
|
for(int8_t i = MAX_TX_BUFFER - 1; i >= 0; i--) {
|
|
if(this->index[i] < MAX_TX_BUFFER) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
bool somfy_tx_queue_t::peek(somfy_tx_t *tx) const {
|
|
const int8_t i = this->oldest();
|
|
if(i < 0) return false;
|
|
memcpy(tx, &this->items[this->index[i]], sizeof(somfy_tx_t));
|
|
return true;
|
|
}
|
|
bool somfy_tx_queue_t::pop(somfy_tx_t *tx) {
|
|
const int8_t i = this->oldest();
|
|
if(i < 0) return false;
|
|
uint8_t ndx = this->index[i];
|
|
memcpy(tx, &this->items[ndx], sizeof(somfy_tx_t));
|
|
this->items[ndx].clear();
|
|
if(this->length > 0) this->length--;
|
|
this->index[i] = 255;
|
|
return true;
|
|
}
|
|
void somfy_tx_queue_t::push(uint8_t hwsync, uint8_t *payload, uint8_t bit_length) {
|
|
if(this->length >= MAX_TX_BUFFER) {
|
|
// We have overflowed the buffer simply empty the last item
|
|
// in this instance we will simply throw it away.
|
|
uint8_t ndx = this->index[MAX_TX_BUFFER - 1];
|
|
if(ndx < MAX_TX_BUFFER) this->items[ndx].clear();
|
|
this->index[MAX_TX_BUFFER - 1] = 255;
|
|
this->length--;
|
|
}
|
|
uint8_t first = 0;
|
|
// Place this record in the first empty slot. There will
|
|
// be one since we cleared a space above should there
|
|
// be an overflow.
|
|
for(uint8_t i = 0; i < MAX_TX_BUFFER; i++) {
|
|
if(this->items[i].bit_length == 0) {
|
|
first = i;
|
|
this->items[i].bit_length = bit_length;
|
|
this->items[i].hwsync = hwsync;
|
|
memcpy(&this->items[i].payload, payload, sizeof(this->items[i].payload));
|
|
break;
|
|
}
|
|
}
|
|
// Move the index so that it is the at position 0. The oldest item will fall off.
|
|
for(uint8_t i = MAX_TX_BUFFER - 1; i > 0; i--) {
|
|
this->index[i] = this->index[i - 1];
|
|
}
|
|
this->length++;
|
|
// When popping from the queue we always pull from the end
|
|
this->index[0] = first;
|
|
}
|
|
void encodeTxJob(somfy_tx_job_t &job, somfy_frame_t &frame, uint8_t repeat) {
|
|
frame.encodeFrame(job.tx.payload);
|
|
job.tx.hwsync = frame.bitLength == 56 ? 2 : 12;
|
|
job.tx.bit_length = frame.bitLength;
|
|
job.frame = frame;
|
|
if(repeat > TX_MAX_REPEATS) {
|
|
ESP_LOGW(TAG, "Limiting %u repeats to %u", repeat, TX_MAX_REPEATS);
|
|
repeat = TX_MAX_REPEATS;
|
|
}
|
|
job.repeats = repeat;
|
|
}
|
|
void encodeRepeatJob(somfy_tx_job_t &job, somfy_frame_t &frame, uint8_t repeat) {
|
|
encodeTxJob(job, frame, repeat);
|
|
job.firstRepeat = frame.repeats + 2;
|
|
}
|
|
void noteRepeatQueued(somfy_frame_t &frame, const somfy_tx_job_t &job) {
|
|
// Only advance the counter for frames that will go on air.
|
|
frame.repeats += job.repeats + 1;
|
|
}
|