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.");
154 !this->gdo0_pin_->digital_read()) {
160 uint8_t rx_bytes = this->
state_.NUM_RXBYTES;
161 bool overflow = this->
state_.RXFIFO_OVERFLOW;
162 if (overflow || rx_bytes == 0) {
163 ESP_LOGW(TAG,
"RX FIFO overflow, flushing");
172 uint8_t payload_length, expected_rx;
175 expected_rx = payload_length + 1;
177 payload_length = this->
state_.PKTLEN;
178 expected_rx = payload_length;
180 if (payload_length == 0 || payload_length > 64 || rx_bytes != expected_rx) {
181 ESP_LOGW(TAG,
"Invalid packet: rx_bytes %u, payload_length %u", rx_bytes, payload_length);
188 this->
packet_.resize(payload_length);
194 float rssi = (this->
state_.RSSI * RSSI_STEP) - RSSI_OFFSET;
195 bool crc_ok = (this->
state_.LQI & STATUS_CRC_OK_MASK) != 0;
196 uint8_t lqi = this->
state_.LQI & STATUS_LQI_MASK;
197 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");
238 ESP_LOGW(TAG,
"Timed out waiting for TX state!");
243 ESP_LOGV(TAG,
"Beginning RX sequence");
256 ESP_LOGV(TAG,
"Setting IDLE state");
261 uint32_t start =
millis();
262 while (
millis() - start < timeout_ms) {
265 if (s == target_state) {
279 uint8_t index =
static_cast<uint8_t
>(cmd);
290 uint8_t index =
static_cast<uint8_t
>(reg);
298 uint8_t index =
static_cast<uint8_t
>(reg);
299 this->
state_.regs()[index] = value;
304 uint8_t index =
static_cast<uint8_t
>(reg);
306 this->
write_byte(index | BUS_WRITE | BUS_BURST);
312 uint8_t index =
static_cast<uint8_t
>(reg);
314 this->
write_byte(index | BUS_READ | BUS_BURST);
320 uint8_t index =
static_cast<uint8_t
>(reg);
322 this->
write_byte(index | BUS_READ | BUS_BURST);
341 ESP_LOGW(TAG,
"TX timeout");
357 int32_t freq =
static_cast<int32_t
>(this->
state_.FREQ2 << 16 | this->
state_.FREQ1 << 8 | this->
state_.FREQ0) *
358 XTAL_FREQUENCY / (1 << 16);
360 if (freq >= 300000000 && freq <= 348000000) {
362 }
else if (freq >= 378000000 && freq <= 464000000) {
364 }
else if (freq >= 779000000 && freq < 900000000) {
366 }
else if (freq >= 900000000 && freq <= 928000000) {
384 this->
state_.CLOSE_IN_RX =
static_cast<uint8_t
>(value);
391 this->
state_.DEM_DCFILT_OFF = value ? 0 : 1;
398 int32_t freq =
static_cast<int32_t
>(value * (1 << 16) / XTAL_FREQUENCY);
399 this->
state_.FREQ2 =
static_cast<uint8_t
>(freq >> 16);
400 this->
state_.FREQ1 =
static_cast<uint8_t
>(freq >> 8);
401 this->
state_.FREQ0 =
static_cast<uint8_t
>(freq);
412 this->
state_.FREQ_IF = value * (1 << 10) / XTAL_FREQUENCY;
421 split_float(XTAL_FREQUENCY / (value * 8), 2, e,
m);
422 this->
state_.CHANBW_E = e;
423 this->
state_.CHANBW_M =
static_cast<uint8_t
>(
m);
430 this->
state_.CHANNR = value;
441 split_float(value * (1 << 18) / XTAL_FREQUENCY, 8, e,
m);
442 this->
state_.CHANSPC_E = e;
443 this->
state_.CHANSPC_M =
static_cast<uint8_t
>(
m);
453 split_float(value * (1 << 17) / XTAL_FREQUENCY, 3, e,
m);
454 this->
state_.DEVIATION_E = e;
455 this->
state_.DEVIATION_M =
static_cast<uint8_t
>(
m);
462 this->
state_.DEVIATION_E = 0;
463 this->
state_.DEVIATION_M = value - 1;
472 split_float(value * (1 << 28) / XTAL_FREQUENCY, 8, e,
m);
474 this->
state_.DRATE_M =
static_cast<uint8_t
>(
m);
482 this->
state_.SYNC_MODE =
static_cast<uint8_t
>(value);
489 this->
state_.CARRIER_SENSE_ABOVE_THRESHOLD = value ? 1 : 0;
496 this->
state_.MOD_FORMAT =
static_cast<uint8_t
>(value);
508 this->
state_.MANCHESTER_EN = value ? 1 : 0;
515 this->
state_.NUM_PREAMBLE = value;
522 this->
state_.SYNC1 = value;
529 this->
state_.SYNC0 = value;
536 this->
state_.MAGN_TARGET =
static_cast<uint8_t
>(value);
543 this->
state_.MAX_LNA_GAIN =
static_cast<uint8_t
>(value);
550 this->
state_.MAX_DVGA_GAIN =
static_cast<uint8_t
>(value);
557 this->
state_.CARRIER_SENSE_ABS_THR =
static_cast<uint8_t
>(value & 0b1111);
564 this->
state_.CARRIER_SENSE_REL_THR =
static_cast<uint8_t
>(value);
571 this->
state_.AGC_LNA_PRIORITY = value ? 1 : 0;
578 this->
state_.FILTER_LENGTH =
static_cast<uint8_t
>(value);
585 this->
state_.FILTER_LENGTH =
static_cast<uint8_t
>(value);
592 this->
state_.AGC_FREEZE =
static_cast<uint8_t
>(value);
599 this->
state_.WAIT_TIME =
static_cast<uint8_t
>(value);
606 this->
state_.HYST_LEVEL =
static_cast<uint8_t
>(value);
617 this->
state_.GDO0_CFG = 0x01;
619 this->
state_.FIFO_THR = 15;
621 this->
state_.APPEND_STATUS = 0;
624 this->
state_.GDO0_CFG = 0x0D;
639 this->
state_.PKTLEN = value;
648 this->
state_.CRC_EN = value ? 1 : 0;
655 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)
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)