Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libretiny: replace ledc with libretiny_pwm #16

Merged
merged 3 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ esphome/components/lcd_menu/* @numo68
esphome/components/ld2410/* @regevbr @sebcaps
esphome/components/ledc/* @OttoWinter
esphome/components/libretiny/* @kuba2k2
esphome/components/libretiny_pwm/* @kuba2k2
esphome/components/light/* @esphome/core
esphome/components/lilygo_t5_47/touchscreen/* @jesserockz
esphome/components/lock/* @esphome/core
Expand Down
2 changes: 1 addition & 1 deletion esphome/components/ledc/ledc_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "esphome/core/automation.h"
#include "esphome/components/output/float_output.h"

#if defined(USE_ESP32) || defined(USE_LIBRETINY)
#ifdef USE_ESP32

namespace esphome {
namespace ledc {
Expand Down
2 changes: 1 addition & 1 deletion esphome/components/ledc/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
CONF_PIN,
)

CONFLICTS_WITH = ["esp8266", "rp2040"]
DEPENDENCIES = ["esp32"]


def calc_max_frequency(bit_depth):
Expand Down
1 change: 1 addition & 0 deletions esphome/components/libretiny_pwm/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CODEOWNERS = ["@kuba2k2"]
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
#include "ledc_output.h"
#include "libretiny_pwm.h"
#include "esphome/core/log.h"

#ifdef USE_LIBRETINY

namespace esphome {
namespace ledc {
namespace libretiny_pwm {

static const char *const TAG = "ledc.output";
static const char *const TAG = "libretiny.pwm";

uint8_t next_ledc_channel = 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)

void LEDCOutput::write_state(float state) {
void LibreTinyPWM::write_state(float state) {
if (!initialized_) {
ESP_LOGW(TAG, "LEDC output hasn't been initialized yet!");
ESP_LOGW(TAG, "LibreTinyPWM output hasn't been initialized yet!");
return;
}

Expand All @@ -27,18 +25,18 @@ void LEDCOutput::write_state(float state) {
analogWrite(this->pin_->get_pin(), duty); // NOLINT
}

void LEDCOutput::setup() {
void LibreTinyPWM::setup() {
this->update_frequency(this->frequency_);
this->turn_off();
}

void LEDCOutput::dump_config() {
void LibreTinyPWM::dump_config() {
ESP_LOGCONFIG(TAG, "PWM Output:");
LOG_PIN(" Pin ", this->pin_);
ESP_LOGCONFIG(TAG, " Frequency: %.1f Hz", this->frequency_);
}

void LEDCOutput::update_frequency(float frequency) {
void LibreTinyPWM::update_frequency(float frequency) {
this->bit_depth_ = 10;
this->frequency_ = frequency;
// force changing the frequency by removing PWM mode
Expand All @@ -50,7 +48,7 @@ void LEDCOutput::update_frequency(float frequency) {
this->write_state(this->duty_);
}

} // namespace ledc
} // namespace libretiny_pwm
} // namespace esphome

#endif
55 changes: 55 additions & 0 deletions esphome/components/libretiny_pwm/libretiny_pwm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include "esphome/core/automation.h"
#include "esphome/components/output/float_output.h"

#ifdef USE_LIBRETINY

namespace esphome {
namespace libretiny_pwm {

class LibreTinyPWM : public output::FloatOutput, public Component {
public:
explicit LibreTinyPWM(InternalGPIOPin *pin) : pin_(pin) {}

void set_frequency(float frequency) { this->frequency_ = frequency; }
/// Dynamically change frequency at runtime
void update_frequency(float frequency) override;

/// Setup LibreTinyPWM.
void setup() override;
void dump_config() override;
/// HARDWARE setup priority
float get_setup_priority() const override { return setup_priority::HARDWARE; }

/// Override FloatOutput's write_state.
void write_state(float state) override;

protected:
InternalGPIOPin *pin_;
uint8_t bit_depth_{};
float frequency_{};
float duty_{0.0f};
bool initialized_ = false;
};

template<typename... Ts> class SetFrequencyAction : public Action<Ts...> {
public:
SetFrequencyAction(LibreTinyPWM *parent) : parent_(parent) {}
TEMPLATABLE_VALUE(float, frequency);

void play(Ts... x) {
float freq = this->frequency_.value(x...);
this->parent_->update_frequency(freq);
}

protected:
LibreTinyPWM *parent_;
};

} // namespace libretiny_pwm
} // namespace esphome

#endif
74 changes: 74 additions & 0 deletions esphome/components/libretiny_pwm/output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from esphome import pins, automation
from esphome.components import output
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.const import (
CONF_FREQUENCY,
CONF_ID,
CONF_PIN,
)

CONFLICTS_WITH = ["esp8266", "esp32", "rp2040"]
catalin2402 marked this conversation as resolved.
Show resolved Hide resolved


def calc_max_frequency(bit_depth):
return 80e6 / (2**bit_depth)


def calc_min_frequency(bit_depth):
max_div_num = ((2**20) - 1) / 256.0
return 80e6 / (max_div_num * (2**bit_depth))


def validate_frequency(value):
catalin2402 marked this conversation as resolved.
Show resolved Hide resolved
value = cv.frequency(value)
min_freq = calc_min_frequency(20)
max_freq = calc_max_frequency(1)
if value < min_freq:
raise cv.Invalid(
f"This frequency setting is not possible, please choose a higher frequency (at least {int(min_freq)}Hz)"
)
if value > max_freq:
raise cv.Invalid(
f"This frequency setting is not possible, please choose a lower frequency (at most {int(max_freq)}Hz)"
)
return value


libretinypwm_ns = cg.esphome_ns.namespace("libretiny_pwm")
LibreTinyPWM = libretinypwm_ns.class_("LibreTinyPWM", output.FloatOutput, cg.Component)
SetFrequencyAction = libretinypwm_ns.class_("SetFrequencyAction", automation.Action)

CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
{
cv.Required(CONF_ID): cv.declare_id(LibreTinyPWM),
cv.Required(CONF_PIN): pins.internal_gpio_output_pin_schema,
cv.Optional(CONF_FREQUENCY, default="1kHz"): cv.frequency,
}
).extend(cv.COMPONENT_SCHEMA)


async def to_code(config):
gpio = await cg.gpio_pin_expression(config[CONF_PIN])
var = cg.new_Pvariable(config[CONF_ID], gpio)
await cg.register_component(var, config)
await output.register_output(var, config)
cg.add(var.set_frequency(config[CONF_FREQUENCY]))


@automation.register_action(
"output.libretiny_pwm.set_frequency",
SetFrequencyAction,
cv.Schema(
{
cv.Required(CONF_ID): cv.use_id(LibreTinyPWM),
cv.Required(CONF_FREQUENCY): cv.templatable(validate_frequency),
}
),
)
async def libretiny_pwm_set_frequency_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
template_ = await cg.templatable(config[CONF_FREQUENCY], args, float)
cg.add(var.set_frequency(template_))
return var