refactor: move the radio into Transceiver.cpp

The CC1101 setup, receive decoding, radio task and frequency scan move out
of Somfy.cpp, and their types out of Somfy.h into Transceiver.h, which
Somfy.h includes. The code is unchanged apart from the bit length the
radio was set up for: bit_length becomes radioBitLength, shared with the
remotes that send without one.

The radio's fromJSON stays in Somfy.cpp for now so the JSON parsing can
move into one file: ArduinoJson costs flash in every file that uses it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-13 20:31:16 +02:00
parent 4cb676a7a7
commit 0a329cafb8
4 changed files with 1077 additions and 1041 deletions

View file

@ -26,6 +26,7 @@
#include "TxBuffer.h"
#include "RadioScheduler.h"
#include "ShadeMotion.h"
#include "Transceiver.h"
enum class group_types : byte {
channel = 0x00
};
@ -56,49 +57,6 @@ enum class tilt_types : byte {
euromode = 0x04
};
#define MAX_TIMINGS 300
#define MAX_RX_BUFFER 3
typedef enum {
waiting_synchro = 0,
receiving_data = 1,
complete = 2
} t_status;
struct somfy_rx_t {
void clear() {
this->status = t_status::waiting_synchro;
this->bit_length = 56;
this->cpt_synchro_hw = 0;
this->cpt_bits = 0;
this->previous_bit = 0;
this->waiting_half_symbol = false;
memset(this->payload, 0, sizeof(this->payload));
memset(this->pulses, 0, sizeof(this->pulses));
this->pulseCount = 0;
}
t_status status;
uint8_t bit_length = 56;
uint8_t cpt_synchro_hw = 0;
uint8_t cpt_bits = 0;
uint8_t previous_bit = 0;
bool waiting_half_symbol;
uint8_t payload[10];
unsigned int pulses[MAX_TIMINGS];
uint16_t pulseCount = 0;
};
// A simple FIFO queue to hold rx buffers. We are using
// a byte index to make it so we don't have to reorganize
// the storage each time we push or pop.
struct somfy_rx_queue_t {
void init();
uint8_t length = 0;
uint8_t index[MAX_RX_BUFFER];
somfy_rx_t items[MAX_RX_BUFFER];
void push(somfy_rx_t *rx);
bool pop(somfy_rx_t *rx);
};
enum class somfy_flags_t : byte {
SunFlag = 0x01,
SunSensor = 0x02,
@ -352,73 +310,6 @@ class SomfyGroup : public SomfyRemote {
bool publish(const char *topic, uint16_t val, bool retain = false);
bool publish(const char *topic, bool val, bool retain = false);
};
struct transceiver_config_t {
bool printBuffer = false;
bool enabled = false;
uint8_t type = 56; // 56 or 80 bit protocol.
radio_proto proto = radio_proto::RTS;
uint8_t SCKPin = 18;
uint8_t TXPin = 13;
uint8_t RXPin = 12;
uint8_t MOSIPin = 23;
uint8_t MISOPin = 19;
uint8_t CSNPin = 5;
bool radioInit = false;
float frequency = 433.42; // Basic frequency
float deviation = 47.60; // Set the Frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz.
float rxBandwidth = 99.97; // Receive bandwidth in kHz. Value from 58.03 to 812.50. Default is 99.97kHz.
int8_t txPower = 10; // Transmission power {-30, -20, -15, -10, -6, 0, 5, 7, 10, 11, 12}. Default is 12.
bool noiseDetection = false; // Disable RX interrupt when RF noise is detected (>100 pulses/10s)
void fromJSON(JsonObject& obj);
void save();
void load();
void apply();
// Removes a key no longer used from the open CC1101 namespace.
void removeNVSKey(Preferences &pref, const char *key);
};
class Transceiver {
private:
static void handleReceive();
static void txTask(void *arg);
bool _received = false;
somfy_frame_t frame;
// Only touched under the TX queue lock.
RadioScheduler sched;
void startTxTask();
bool transmitJob(somfy_tx_job_t &job);
// Sends a job taken off the queue and leaves a frame beat after it.
void runJob(somfy_tx_job_t &job);
public:
transceiver_config_t config;
bool printBuffer = false;
bool fromJSON(JsonObject& obj);
// Swaps in, saves and applies the config.
void setConfig(const transceiver_config_t &cfg);
bool begin();
void loop();
bool end();
bool receive(somfy_rx_t *rx);
void clearReceived();
void enableReceive();
void disableReceive();
somfy_frame_t& lastFrame();
void sendFrame(byte *frame, uint8_t sync, uint8_t bitLength = 56);
// Hands a job to the radio task, see RadioScheduler::submit(). Returns its
// ticket, 0 when the radio can't take it. Safe from any task.
uint32_t submitTx(somfy_tx_job_t &job, bool priority = false, uint16_t delayMs = 0);
void suspendTx(uint8_t reason);
void resumeTx(uint8_t reason);
bool txSuspended();
bool txHasRoom();
void beginTransmit();
void endTransmit();
void emitFrame(somfy_frame_t *frame, somfy_rx_t *rx = nullptr);
void beginFrequencyScan();
void endFrequencyScan();
void processFrequencyScan(bool received = false);
void emitFrequencyScan(uint8_t num = 255);
bool usesPin(uint8_t pin);
};
class SomfyShadeController {
protected:
uint8_t m_shadeIds[SOMFY_MAX_SHADES];