Skip to content

Instantly share code, notes, and snippets.

@vinsce
Created February 25, 2025 22:40
Show Gist options
  • Save vinsce/556183c7b0e7084341216ef5a2ecd65c to your computer and use it in GitHub Desktop.
Save vinsce/556183c7b0e7084341216ef5a2ecd65c to your computer and use it in GitHub Desktop.
CC1101 simple ESPHome component
# See: https://esphome.io/guides/contributing.html#extras
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.const import (
CONF_ID,
CONF_FREQUENCY,
)
# Mark the component to depend on other components.
# If the user hasn’t explicitly added these components in their configuration, a validation error will be generated.
DEPENDENCIES = [ ]
# Automatically load a component if the user hasn’t added it manually
AUTO_LOAD = [ ]
# Mark this component to accept an array of configurations.
# If this is an integer instead of a boolean, validation will only permit the given number of entries.
MULTI_CONF = False
# GitHub usernames or team names of people that are responsible for this component
CODEOWNERS = ["@vinsce"]
# Define constants for configuration keys
CONF_SCK_PIN = "sck_pin"
CONF_MISO_PIN = "miso_pin"
CONF_MOSI_PIN = "mosi_pin"
CONF_CSN_PIN = "csn_pin"
CONF_GDO0_PIN = "gdo0_pin"
CONF_BANDWIDTH = "bandwidth"
# C++ namespace
ns = cg.esphome_ns.namespace("cc1101")
CC1101 = ns.class_("CC1101", cg.Component)
# The configuration schema to validate the user config against
CONFIG_SCHEMA = cv.COMPONENT_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(CC1101),
#cv.Required(CONF_NAME): cv.string,
# TODO review input/output pins
cv.Required(CONF_SCK_PIN): pins.gpio_output_pin_schema,
cv.Required(CONF_MISO_PIN): pins.gpio_output_pin_schema,
cv.Required(CONF_MOSI_PIN): pins.gpio_output_pin_schema,
cv.Required(CONF_CSN_PIN): pins.gpio_output_pin_schema,
cv.Required(CONF_GDO0_PIN): pins.gpio_input_pin_schema,
cv.Optional(CONF_BANDWIDTH, default=200.0): cv.float_,
cv.Optional(CONF_FREQUENCY, default=868.65): cv.float_,
}
)
async def to_code(config):
sck_pin = await cg.gpio_pin_expression(config[CONF_SCK_PIN])
miso_pin = await cg.gpio_pin_expression(config[CONF_MISO_PIN])
mosi_pin = await cg.gpio_pin_expression(config[CONF_MOSI_PIN])
csn_pin = await cg.gpio_pin_expression(config[CONF_CSN_PIN])
gd0_pin = await cg.gpio_pin_expression(config[CONF_GDO0_PIN])
# Declare new component
# Will create a new pointer:
# transceiver = new cc1101::CC1101();
var = cg.new_Pvariable(config[CONF_ID], sck_pin, miso_pin, mosi_pin, csn_pin, gd0_pin)
# Will configure and register the component:
# transceiver->set_update_interval(60000);
# transceiver->set_component_source("cc1101");
# App.register_component(transceiver);
await cg.register_component(var, config)
# cg.add is used to add a piece of code to the generated main.cpp
# transceiver->set_bandwidth(200);
cg.add(var.set_bandwidth(config[CONF_BANDWIDTH]))
cg.add(var.set_frequency(config[CONF_FREQUENCY]))
#include "esphome/core/log.h"
#include "cc1101.h"
// #include <driver/gpio.h>
namespace esphome {
namespace cc1101 {
static const char *const TAG = "cc1101";
CC1101::CC1101(InternalGPIOPin *sck_pin, InternalGPIOPin *miso_pin, InternalGPIOPin *mosi_pin, InternalGPIOPin *csn_pin, InternalGPIOPin *gdo0_pin) {
this->SCK_ = sck_pin;
this->MISO_ = miso_pin;
this->MOSI_ = mosi_pin;
this->CSN_ = csn_pin;
this->GDO0_ = gdo0_pin;
this->_moduleNumber = 1;
}
void CC1101::set_bandwidth(float bandwidth) { bandwidth_ = bandwidth; }
void CC1101::set_frequency(float frequency) { frequency_ = frequency; }
/**
* special setup() method that will be called once to set up the component
* at the time the setup() method is called, all the setters generated by the Python codebase have already run and the all fields are set for your class.
* The setup() method should set up the communication interface for the component and check if communication works (if not, it should call mark_failed()).
*
*/
void CC1101::setup() {
ESP_LOGI(TAG, "CC1101 initialized.");
pinMode(GDO0_->get_pin(), INPUT);
ELECHOUSE_cc1101.addSpiPin(SCK_->get_pin(), MISO_->get_pin(), MOSI_->get_pin(), CSN_->get_pin(), _moduleNumber);
ELECHOUSE_cc1101.setModul(_moduleNumber);
ELECHOUSE_cc1101.Init();
ELECHOUSE_cc1101.setRxBW(bandwidth_);
ELECHOUSE_cc1101.setMHZ(frequency_);
ELECHOUSE_cc1101.SetRx();
}
// Components should dump their configuration using ESP_LOGCONFIG at startup in dump_config()
void CC1101::dump_config() {
ESP_LOGCONFIG(TAG, "CC1101:");
LOG_PIN(" GDO0 Pin: ", this->GDO0_);
LOG_PIN(" SCK Pin: ", this->SCK_);
LOG_PIN(" MISO Pin: ", this->MISO_);
LOG_PIN(" MOSI Pin: ", this->MOSI_);
LOG_PIN(" CSN Pin: ", this->CSN_);
ESP_LOGCONFIG(TAG, " Bandwith: %.2f KHz", this->bandwidth_);
ESP_LOGCONFIG(TAG, " Frequency: %.2f MHz", this->frequency_);
}
} // namespace cc1101
} // namespace esphome
#pragma once
#include <ELECHOUSE_CC1101_SRC_DRV.h>
#include "esphome/core/component.h"
#include <esphome/core/hal.h>
namespace esphome {
namespace cc1101 {
class CC1101 : public Component {
public:
CC1101(InternalGPIOPin *sck_pin, InternalGPIOPin *miso_pin, InternalGPIOPin *mosi_pin, InternalGPIOPin *csn_pin, InternalGPIOPin *gdo0_pin);
void set_bandwidth(float bandwidth);
void set_frequency(float frequency);
void setup() override;
void dump_config() override;
protected:
InternalGPIOPin *SCK_;
InternalGPIOPin *MISO_;
InternalGPIOPin *MOSI_;
InternalGPIOPin *CSN_;
InternalGPIOPin *GDO0_;
float bandwidth_;
float frequency_;
float _moduleNumber;
};
} // namespace cc1101
} // namespace esphome
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment