9static const char *
const TAG =
"cc1101";
11static void split_float(
float value,
int mbits, uint8_t &e, uint32_t &
m) {
13 float m_tmp = std::frexp(value, &e_tmp);
19 e =
static_cast<uint8_t
>(e_tmp - mbits - 1);
20 m =
static_cast<uint32_t
>(((m_tmp * 2 - 1) * (1 << (mbits + 1))) + 1) >> 1;
21 if (
m == (1UL << mbits)) {
30 this->
state_.GDO2_CFG = 0x0D;
31 this->
state_.GDO1_CFG = 0x2E;
32 this->
state_.GDO0_CFG = 0x0D;
36 this->
state_.PKTLEN = 0xFF;
37 this->
state_.APPEND_STATUS = 1;
38 this->
state_.LENGTH_CONFIG = 1;
40 this->
state_.WHITE_DATA = 1;
41 this->
state_.FREQ_IF = 0x0F;
45 this->
state_.DRATE_E = 0x0C;
46 this->
state_.CHANBW_E = 0x02;
47 this->
state_.DRATE_M = 0x22;
48 this->
state_.SYNC_MODE = 2;
49 this->
state_.CHANSPC_E = 2;
50 this->
state_.NUM_PREAMBLE = 2;
51 this->
state_.CHANSPC_M = 0xF8;
52 this->
state_.DEVIATION_M = 7;
53 this->
state_.DEVIATION_E = 4;
56 this->
state_.PO_TIMEOUT = 1;
57 this->
state_.FOC_LIMIT = 2;
58 this->
state_.FOC_POST_K = 1;
59 this->
state_.FOC_PRE_K = 2;
60 this->
state_.FOC_BS_CS_GATE = 1;
61 this->
state_.BS_POST_KP = 1;
62 this->
state_.BS_POST_KI = 1;
63 this->
state_.BS_PRE_KP = 2;
64 this->
state_.BS_PRE_KI = 1;
65 this->
state_.MAGN_TARGET = 3;
66 this->
state_.AGC_LNA_PRIORITY = 1;
67 this->
state_.FILTER_LENGTH = 1;
68 this->
state_.WAIT_TIME = 1;
69 this->
state_.HYST_LEVEL = 2;
70 this->
state_.WOREVT1 = 0x87;
71 this->
state_.WOREVT0 = 0x6B;
75 this->
state_.MIX_CURRENT = 2;
76 this->
state_.LODIV_BUF_CURRENT_RX = 1;
77 this->
state_.LNA2MIX_CURRENT = 1;
78 this->
state_.LNA_CURRENT = 1;
79 this->
state_.LODIV_BUF_CURRENT_TX = 1;
80 this->
state_.FSCAL3_LO = 9;
81 this->
state_.CHP_CURR_CAL_EN = 2;
82 this->
state_.FSCAL3_HI = 2;
83 this->
state_.FSCAL2 = 0x0A;
84 this->
state_.FSCAL1 = 0x20;
85 this->
state_.FSCAL0 = 0x0D;
86 this->
state_.RCCTRL1 = 0x41;
87 this->
state_.FSTEST = 0x59;
89 this->
state_.AGCTEST = 0x3F;
93 this->
state_.VCO_SEL_CAL_EN = 1;
97 this->
state_.PKT_FORMAT = 3;
98 this->
state_.LENGTH_CONFIG = 2;
99 this->
state_.FS_AUTOCAL = 1;
122 ESP_LOGD(TAG,
"CC1101 found! Chip ID: 0x%04X", this->
chip_id_);
123 if (this->
state_.VERSION == 0 || this->state_.PARTNUM == 0xFF) {
124 ESP_LOGE(TAG,
"Failed to verify CC1101.");
157 !this->gdo0_pin_->digital_read()) {
163 uint8_t rx_bytes = this->
state_.NUM_RXBYTES;
164 bool overflow = this->
state_.RXFIFO_OVERFLOW;
165 if (overflow || rx_bytes == 0) {
166 ESP_LOGW(TAG,
"RX FIFO overflow, flushing");
174 uint8_t payload_length, expected_rx;
177 expected_rx = payload_length + 1;
179 payload_length = this->
state_.PKTLEN;
180 expected_rx = payload_length;
182 if (payload_length == 0 || payload_length > 64 || rx_bytes != expected_rx) {
183 ESP_LOGW(TAG,
"Invalid packet: rx_bytes %u, payload_length %u", rx_bytes, payload_length);
189 this->
packet_.resize(payload_length);
195 float rssi = (this->
state_.RSSI * RSSI_STEP) - RSSI_OFFSET;
196 bool crc_ok = (this->
state_.LQI & STATUS_CRC_OK_MASK) != 0;
197 uint8_t lqi = this->
state_.LQI & STATUS_LQI_MASK;
198 if (this->
state_.CRC_EN == 0 || crc_ok) {
209 static const char *
const MODULATION_NAMES[] = {
"2-FSK",
"GFSK",
"UNUSED",
"ASK/OOK",
210 "4-FSK",
"UNUSED",
"UNUSED",
"MSK"};
211 int32_t freq =
static_cast<int32_t
>(this->
state_.FREQ2 << 16 | this->
state_.FREQ1 << 8 | this->
state_.FREQ0) *
212 XTAL_FREQUENCY / (1 << 16);
213 float symbol_rate = (((256.0f + this->
state_.DRATE_M) * (1 << this->
state_.DRATE_E)) / (1 << 28)) * XTAL_FREQUENCY;
214 float bw = XTAL_FREQUENCY / (8.0f * (4 + this->
state_.CHANBW_M) * (1 << this->
state_.CHANBW_E));
215 ESP_LOGCONFIG(TAG,
"CC1101:");
216 LOG_PIN(
" CS Pin: ", this->
cs_);
219 " Frequency: %" PRId32
" Hz\n"
222 " Symbol Rate: %.0f baud\n"
223 " Filter Bandwidth: %.1f Hz\n"
224 " Output Power: %.1f dBm",
225 this->
chip_id_, freq, this->
state_.CHANNR, MODULATION_NAMES[this->state_.MOD_FORMAT & 0x07],
226 symbol_rate, bw, this->output_power_effective_);
232 ESP_LOGV(TAG,
"Beginning TX sequence");
237 ESP_LOGW(TAG,
"Failed to enter TX state!");
242 ESP_LOGV(TAG,
"Beginning RX sequence");
247 ESP_LOGW(TAG,
"Failed to enter RX state!");
257 ESP_LOGV(TAG,
"Setting IDLE state");
262 uint32_t start =
millis();
263 while (
millis() - start < timeout_ms) {
266 if (s == target_state) {
276 for (uint8_t retries = PLL_LOCK_RETRIES; retries > 0; retries--) {
282 if (this->
state_.FSCAL1 != FSCAL1_PLL_NOT_LOCKED) {
285 ESP_LOGW(TAG,
"PLL lock failed, retrying calibration");
288 ESP_LOGE(TAG,
"PLL lock failed after retries");
302 uint8_t index =
static_cast<uint8_t
>(cmd);
313 uint8_t index =
static_cast<uint8_t
>(reg);
321 uint8_t index =
static_cast<uint8_t
>(reg);
322 this->
state_.regs()[index] = value;
327 uint8_t index =
static_cast<uint8_t
>(reg);
329 this->
write_byte(index | BUS_WRITE | BUS_BURST);
335 uint8_t index =
static_cast<uint8_t
>(reg);
337 this->
write_byte(index | BUS_READ | BUS_BURST);
343 uint8_t index =
static_cast<uint8_t
>(reg);
345 this->
write_byte(index | BUS_READ | BUS_BURST);
365 ESP_LOGW(TAG,
"PLL lock failed during TX");
374 ESP_LOGW(TAG,
"TX timeout");
388 int32_t freq =
static_cast<int32_t
>(this->
state_.FREQ2 << 16 | this->
state_.FREQ1 << 8 | this->
state_.FREQ0) *
389 XTAL_FREQUENCY / (1 << 16);
391 if (freq >= 300000000 && freq <= 348000000) {
393 }
else if (freq >= 378000000 && freq <= 464000000) {
395 }
else if (freq >= 779000000 && freq < 900000000) {
397 }
else if (freq >= 900000000 && freq <= 928000000) {
415 this->
state_.CLOSE_IN_RX =
static_cast<uint8_t
>(value);
422 this->
state_.DEM_DCFILT_OFF = value ? 0 : 1;
429 int32_t freq =
static_cast<int32_t
>(value * (1 << 16) / XTAL_FREQUENCY);
430 this->
state_.FREQ2 =
static_cast<uint8_t
>(freq >> 16);
431 this->
state_.FREQ1 =
static_cast<uint8_t
>(freq >> 8);
432 this->
state_.FREQ0 =
static_cast<uint8_t
>(freq);
443 this->
state_.FREQ_IF = value * (1 << 10) / XTAL_FREQUENCY;
452 split_float(XTAL_FREQUENCY / (value * 8), 2, e,
m);
453 this->
state_.CHANBW_E = e;
454 this->
state_.CHANBW_M =
static_cast<uint8_t
>(
m);
461 this->
state_.CHANNR = value;
472 split_float(value * (1 << 18) / XTAL_FREQUENCY, 8, e,
m);
473 this->
state_.CHANSPC_E = e;
474 this->
state_.CHANSPC_M =
static_cast<uint8_t
>(
m);
484 split_float(value * (1 << 17) / XTAL_FREQUENCY, 3, e,
m);
485 this->
state_.DEVIATION_E = e;
486 this->
state_.DEVIATION_M =
static_cast<uint8_t
>(
m);
493 this->
state_.DEVIATION_E = 0;
494 this->
state_.DEVIATION_M = value - 1;
503 split_float(value * (1 << 28) / XTAL_FREQUENCY, 8, e,
m);
505 this->
state_.DRATE_M =
static_cast<uint8_t
>(
m);
513 this->
state_.SYNC_MODE =
static_cast<uint8_t
>(value);
520 this->
state_.CARRIER_SENSE_ABOVE_THRESHOLD = value ? 1 : 0;
527 this->
state_.MOD_FORMAT =
static_cast<uint8_t
>(value);
539 this->
state_.MANCHESTER_EN = value ? 1 : 0;
546 this->
state_.NUM_PREAMBLE = value;
553 this->
state_.SYNC1 = value;
560 this->
state_.SYNC0 = value;
567 this->
state_.MAGN_TARGET =
static_cast<uint8_t
>(value);
574 this->
state_.MAX_LNA_GAIN =
static_cast<uint8_t
>(value);
581 this->
state_.MAX_DVGA_GAIN =
static_cast<uint8_t
>(value);
588 this->
state_.CARRIER_SENSE_ABS_THR =
static_cast<uint8_t
>(value & 0b1111);
595 this->
state_.CARRIER_SENSE_REL_THR =
static_cast<uint8_t
>(value);
602 this->
state_.AGC_LNA_PRIORITY = value ? 1 : 0;
609 this->
state_.FILTER_LENGTH =
static_cast<uint8_t
>(value);
616 this->
state_.FILTER_LENGTH =
static_cast<uint8_t
>(value);
623 this->
state_.AGC_FREEZE =
static_cast<uint8_t
>(value);
630 this->
state_.WAIT_TIME =
static_cast<uint8_t
>(value);
637 this->
state_.HYST_LEVEL =
static_cast<uint8_t
>(value);
648 this->
state_.GDO0_CFG = 0x01;
650 this->
state_.FIFO_THR = 15;
652 this->
state_.APPEND_STATUS = 0;
655 this->
state_.GDO0_CFG = 0x0D;
670 this->
state_.PKTLEN = value;
679 this->
state_.CRC_EN = value ? 1 : 0;
686 this->
state_.WHITE_DATA = value ? 1 : 0;
virtual void mark_failed()
Mark this component as failed.
void defer(const std::string &name, std::function< void()> &&f)
Defer a callback to the next loop() call.
virtual void pin_mode(gpio::Flags flags)=0
virtual void digital_write(bool value)=0
void trigger(const Ts &...x)
Inform the parent automation that the event has triggered.
void set_packet_mode(bool value)
void set_max_dvga_gain(MaxDvgaGain value)
void set_whitening(bool value)
void set_carrier_sense_above_threshold(bool value)
void write_(Register reg)
void set_sync0(uint8_t value)
void set_freeze(Freeze value)
void set_rx_attenuation(RxAttenuation value)
InternalGPIOPin * gdo0_pin_
void set_symbol_rate(float value)
uint8_t strobe_(Command cmd)
void set_sync_mode(SyncMode value)
void set_fsk_deviation(float value)
void dump_config() override
float output_power_requested_
void set_msk_deviation(uint8_t value)
void set_carrier_sense_rel_thr(CarrierSenseRelThr value)
uint8_t pa_table_[PA_TABLE_SIZE]
void set_lna_priority(bool value)
float output_power_effective_
void set_output_power(float value)
void set_modulation_type(Modulation value)
void set_if_frequency(float value)
void set_frequency(float value)
void set_num_preamble(uint8_t value)
void set_hyst_level(HystLevel value)
void set_filter_bandwidth(float value)
void set_filter_length_fsk_msk(FilterLengthFskMsk value)
void set_crc_enable(bool value)
void set_carrier_sense_abs_thr(int8_t value)
bool enter_calibrated_(State target_state, Command cmd)
void set_magn_target(MagnTarget value)
void set_channel_spacing(float value)
CC1101Error transmit_packet(const std::vector< uint8_t > &packet)
void set_wait_time(WaitTime value)
void set_dc_blocking_filter(bool value)
void set_packet_length(uint8_t value)
void set_manchester(bool value)
std::vector< uint8_t > packet_
void set_channel(uint8_t value)
void set_filter_length_ask_ook(FilterLengthAskOok value)
void set_max_lna_gain(MaxLnaGain value)
Trigger< std::vector< uint8_t >, float, uint8_t > * packet_trigger_
void set_sync1(uint8_t value)
bool wait_for_state_(State target_state, uint32_t timeout_ms=100)
void spi_setup() override
void write_byte(uint8_t data)
uint8_t transfer_byte(uint8_t data)
void write_array(const uint8_t *data, size_t length)
void read_array(uint8_t *data, size_t length)
@ PACKET_FORMAT_ASYNC_SERIAL
void IRAM_ATTR HOT delayMicroseconds(uint32_t us)
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
void IRAM_ATTR HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()
static uint8_t find(const PowerTableItem *items, size_t count, float &dbm_target)