mirror of
https://github.com/esphome/esphome.git
synced 2025-03-27 18:59:00 +01:00
KT0803 FM Transmitter initial commit
This commit is contained in:
parent
7e16cda949
commit
74ca4e04bb
8 changed files with 910 additions and 0 deletions
CODEOWNERS
esphome/components/kt0803
|
@ -219,6 +219,7 @@ esphome/components/json/* @OttoWinter
|
|||
esphome/components/kamstrup_kmp/* @cfeenstra1024
|
||||
esphome/components/key_collector/* @ssieb
|
||||
esphome/components/key_provider/* @ssieb
|
||||
esphome/components/kt0803/* @gabest11
|
||||
esphome/components/kuntze/* @ssieb
|
||||
esphome/components/lcd_menu/* @numo68
|
||||
esphome/components/ld2410/* @regevbr @sebcaps
|
||||
|
|
86
esphome/components/kt0803/__init__.py
Normal file
86
esphome/components/kt0803/__init__.py
Normal file
|
@ -0,0 +1,86 @@
|
|||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.components import i2c, sensor, text_sensor, binary_sensor
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_FREQUENCY,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
)
|
||||
|
||||
CODEOWNERS = ["@gabest11"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["sensor", "text_sensor", "binary_sensor", "number", "switch", "select", "text"]
|
||||
MULTI_CONF = True
|
||||
|
||||
UNIT_MEGA_HERTZ = "MHz"
|
||||
UNIT_KILO_HERTZ = "KHz"
|
||||
UNIT_MILLI_VOLT = "mV"
|
||||
UNIT_MICRO_AMPERE = "mA"
|
||||
UNIT_DECIBEL_MICRO_VOLT = "dBµV"
|
||||
|
||||
ICON_VOLUME_MUTE = "mdi:volume-mute"
|
||||
ICON_EAR_HEARING = "mdi:ear-hearing"
|
||||
ICON_RADIO_TOWER = "mdi:radio-tower"
|
||||
ICON_SLEEP = "mdi:sleep"
|
||||
ICON_SINE_WAVE = "mdi:sine-wave"
|
||||
ICON_RESISTOR = "mdi:resistor"
|
||||
ICON_FORMAT_TEXT = "mdi:format-text"
|
||||
|
||||
kt0803_ns = cg.esphome_ns.namespace("kt0803")
|
||||
KT0803Component = kt0803_ns.class_(
|
||||
"KT0803Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONF_KT0803_ID = "kt0803_id"
|
||||
CONF_CHIP_ID = "chip_id"
|
||||
CONF_PW_OK = "pw_ok"
|
||||
CONF_SLNCID = "slncid"
|
||||
|
||||
SetFrequencyAction = kt0803_ns.class_(
|
||||
"SetFrequencyAction", automation.Action, cg.Parented.template(KT0803Component)
|
||||
)
|
||||
|
||||
ChipId = kt0803_ns.enum("ChipId", True)
|
||||
CHIP_ID = {
|
||||
"KT0803": ChipId.KT0803,
|
||||
"KT0803K": ChipId.KT0803K,
|
||||
"KT0803M": ChipId.KT0803M,
|
||||
"KT0803L": ChipId.KT0803L,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(KT0803Component),
|
||||
cv.Required(CONF_CHIP_ID): cv.enum(CHIP_ID),
|
||||
cv.Optional(CONF_FREQUENCY, default=87.50): cv.float_range(70, 108),
|
||||
cv.Optional(CONF_PW_OK): binary_sensor.binary_sensor_schema(
|
||||
device_class=DEVICE_CLASS_POWER,
|
||||
icon=ICON_RADIO_TOWER,
|
||||
),
|
||||
cv.Optional(CONF_SLNCID): binary_sensor.binary_sensor_schema(
|
||||
device_class=DEVICE_CLASS_EMPTY,
|
||||
icon=ICON_VOLUME_MUTE,
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x3E))
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
cg.add(var.set_chip_id(config.get(CONF_CHIP_ID)))
|
||||
if conf_frequency := config.get(CONF_FREQUENCY):
|
||||
cg.add(var.set_frequency(conf_frequency))
|
||||
if conf_pw_ok := config.get(CONF_PW_OK):
|
||||
s = await binary_sensor.new_binary_sensor(conf_pw_ok)
|
||||
cg.add(var.set_pw_ok_binary_sensor(s))
|
||||
if conf_slncid := config.get(CONF_SLNCID):
|
||||
s = await binary_sensor.new_binary_sensor(conf_slncid)
|
||||
cg.add(var.set_slncid_binary_sensor(s))
|
283
esphome/components/kt0803/kt0803.cpp
Normal file
283
esphome/components/kt0803/kt0803.cpp
Normal file
|
@ -0,0 +1,283 @@
|
|||
#include "kt0803.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
|
||||
namespace esphome {
|
||||
namespace kt0803 {
|
||||
|
||||
// TODO: std::clamp isn't here yet
|
||||
#define clamp(v, lo, hi) std::max(std::min(v, hi), lo)
|
||||
|
||||
static const char *const TAG = "kt0803";
|
||||
|
||||
KT0803Component::KT0803Component() {
|
||||
this->chip_id_ = ChipId::KT0803L;
|
||||
this->reset_ = false;
|
||||
memset(&this->state_, 0, sizeof(this->state_));
|
||||
// set datasheet defaults, except frequency to 87.5MHz
|
||||
this->state_.REG_00 = 0x6B;
|
||||
this->state_.REG_01 = 0xC3;
|
||||
this->state_.REG_02 = 0x40;
|
||||
this->state_.REG_04 = 0x04;
|
||||
this->state_.REG_0E = 0x02;
|
||||
this->state_.REG_10 = 0xA8;
|
||||
this->state_.REG_12 = 0x80;
|
||||
this->state_.REG_13 = 0x80;
|
||||
this->state_.REG_15 = 0xE0;
|
||||
this->state_.REG_26 = 0xA0;
|
||||
}
|
||||
|
||||
bool KT0803Component::check_reg_(uint8_t addr) {
|
||||
switch (addr) { // check KT0803 address range
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x13:
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this->chip_id_ != ChipId::KT0803) {
|
||||
switch (addr) { // check KT0803K/M address range too
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x04:
|
||||
case 0x0B:
|
||||
case 0x0E:
|
||||
case 0x0F:
|
||||
case 0x10:
|
||||
case 0x12:
|
||||
case 0x14:
|
||||
case 0x16:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->chip_id_ == ChipId::KT0803L) {
|
||||
switch (addr) { // check KT0803L address range too
|
||||
case 0x17:
|
||||
case 0x1E:
|
||||
case 0x26:
|
||||
case 0x27:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void KT0803Component::write_reg_(uint8_t addr) {
|
||||
if (addr >= sizeof(this->regs_) || !this->check_reg_(addr)) {
|
||||
ESP_LOGE(TAG, "write_reg_(0x%02X) invalid register address", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (addr == 0x13 && this->state_.PA_CTRL == 1) {
|
||||
ESP_LOGW(TAG, "write_reg_(0x%02X) PA_CTRL = 1 can destroy the device", addr);
|
||||
return; // TODO: remove this when everything tested and works
|
||||
}
|
||||
|
||||
if (this->reset_) {
|
||||
uint8_t value = this->regs_[addr];
|
||||
ESP_LOGV(TAG, "write_reg_(0x%02X) = 0x%02X", addr, value);
|
||||
this->write_byte(addr, value);
|
||||
} else {
|
||||
if (this->get_component_state() & COMPONENT_STATE_LOOP) {
|
||||
ESP_LOGE(TAG, "write_reg_(0x%02X) device was not reset", addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool KT0803Component::read_reg_(uint8_t addr) {
|
||||
if (addr >= sizeof(this->regs_) || !this->check_reg_(addr)) {
|
||||
ESP_LOGE(TAG, "write_reg_(0x%02X) invalid register address", addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t c;
|
||||
if (i2c::ERROR_OK == this->read_register(addr, &c, 1, false)) {
|
||||
this->regs_[addr] = c;
|
||||
return true;
|
||||
}
|
||||
|
||||
ESP_LOGE(TAG, "read_reg_(0x%02X) cannot read register", addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
// overrides
|
||||
|
||||
void KT0803Component::setup() {
|
||||
/*
|
||||
for (size_t addr = 0; addr < 0x2F; addr++) {
|
||||
uint8_t c;
|
||||
if (i2c::ERROR_OK == this->read_register(addr, &c, 1, false)) {
|
||||
ESP_LOGV(TAG, "setup register[%02X]: %02X", addr, c);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
this->reset_ = true;
|
||||
|
||||
for (size_t addr = 0; addr < sizeof(this->state_); addr++) {
|
||||
if (addr != 0x0F && this->check_reg_(addr)) {
|
||||
this->write_reg_(addr);
|
||||
}
|
||||
}
|
||||
|
||||
this->publish_pw_ok();
|
||||
this->publish_slncid();
|
||||
this->publish_frequency();
|
||||
}
|
||||
|
||||
void KT0803Component::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "KT0803:");
|
||||
LOG_I2C_DEVICE(this);
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGE(TAG, "failed!");
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, " Chip: %s", this->get_chip_string().c_str());
|
||||
ESP_LOGCONFIG(TAG, " Frequency: %.2f MHz", this->get_frequency());
|
||||
// TODO: ...and everything else...
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
|
||||
void KT0803Component::update() {
|
||||
if (this->read_reg_(0x0F)) {
|
||||
this->publish_pw_ok();
|
||||
this->publish_slncid();
|
||||
}
|
||||
/*
|
||||
for (size_t addr = 0; addr < 0x2F; addr++) {
|
||||
uint8_t c;
|
||||
if (i2c::ERROR_OK == this->read_register(addr, &c, 1, false)) {
|
||||
ESP_LOGV(TAG, "update register[%02X]: %02X", addr, c);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void KT0803Component::loop() {
|
||||
}
|
||||
|
||||
// config
|
||||
|
||||
void KT0803Component::set_chip_id(ChipId value) {
|
||||
this->chip_id_ = value;
|
||||
}
|
||||
|
||||
ChipId KT0803Component::get_chip_id() {
|
||||
return this->chip_id_;
|
||||
}
|
||||
|
||||
std::string KT0803Component::get_chip_string() const {
|
||||
switch (this->chip_id_) {
|
||||
case ChipId::KT0803:
|
||||
return "KT0803";
|
||||
case ChipId::KT0803K:
|
||||
return "KT0803K";
|
||||
case ChipId::KT0803M:
|
||||
return "KT0803M";
|
||||
case ChipId::KT0803L:
|
||||
return "KT0803L";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void KT0803Component::set_frequency(float value) {
|
||||
if (!(CHSEL_MIN <= value && value <= CHSEL_MAX)) {
|
||||
ESP_LOGE(TAG, "set_frequency(%.2f) invalid (%.2f - %.2f)", value, CHSEL_MIN, CHSEL_MAX);
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t ch = (uint16_t) std::lround(value * 20);
|
||||
this->state_.CHSEL2 = (uint8_t) ((ch >> 9) & 0x07);
|
||||
this->state_.CHSEL1 = (uint8_t) ((ch >> 1) & 0xff);
|
||||
this->state_.CHSEL0 = (uint8_t) ((ch >> 0) & 0x01);
|
||||
this->write_reg_(0x00);
|
||||
this->write_reg_(0x01);
|
||||
this->write_reg_(0x02);
|
||||
|
||||
this->publish_frequency();
|
||||
}
|
||||
|
||||
float KT0803Component::get_frequency() {
|
||||
uint16_t ch = 0;
|
||||
ch |= (uint16_t) this->state_.CHSEL2 << 9;
|
||||
ch |= (uint16_t) this->state_.CHSEL1 << 1;
|
||||
if (this->chip_id_ != ChipId::KT0803) {
|
||||
ch |= (uint16_t) this->state_.CHSEL0 << 0;
|
||||
}
|
||||
return (float) ch / 20;
|
||||
}
|
||||
|
||||
// publish
|
||||
|
||||
void KT0803Component::publish_pw_ok() { this->publish(this->pw_ok_binary_sensor_, this->state_.PW_OK == 1); }
|
||||
|
||||
void KT0803Component::publish_slncid() { this->publish(this->slncid_binary_sensor_, this->state_.SLNCID == 1); }
|
||||
|
||||
void KT0803Component::publish_frequency() { this->publish(this->frequency_number_, this->get_frequency()); }
|
||||
|
||||
void KT0803Component::publish(text_sensor::TextSensor *s, const std::string &state) {
|
||||
if (s != nullptr) {
|
||||
if (!s->has_state() || s->state != state) {
|
||||
s->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KT0803Component::publish(binary_sensor::BinarySensor *s, bool state) {
|
||||
if (s != nullptr) {
|
||||
if (!s->has_state() || s->state != state) {
|
||||
s->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KT0803Component::publish(sensor::Sensor *s, float state) {
|
||||
if (s != nullptr) {
|
||||
if (!s->has_state() || s->state != state) {
|
||||
s->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KT0803Component::publish(number::Number *n, float state) {
|
||||
if (n != nullptr) {
|
||||
if (!n->has_state() || n->state != state) {
|
||||
n->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KT0803Component::publish(switch_::Switch *s, bool state) {
|
||||
if (s != nullptr) {
|
||||
if (s->state != state) { // ?
|
||||
s->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KT0803Component::publish(select::Select *s, size_t index) {
|
||||
if (s != nullptr) {
|
||||
if (auto state = s->at(index)) {
|
||||
if (!s->has_state() || s->state != *state) {
|
||||
s->publish_state(*state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KT0803Component::publish(text::Text *t, const std::string &state) {
|
||||
if (t != nullptr) {
|
||||
if (!t->has_state() || t->state != state) {
|
||||
t->publish_state(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace kt0803
|
||||
} // namespace esphome
|
74
esphome/components/kt0803/kt0803.h
Normal file
74
esphome/components/kt0803/kt0803.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/automation.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/sensor/sensor.h"
|
||||
#include "esphome/components/text_sensor/text_sensor.h"
|
||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "esphome/components/switch/switch.h"
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "esphome/components/text/text.h"
|
||||
#include <string>
|
||||
#include "kt0803defs.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace kt0803 {
|
||||
|
||||
#ifndef SUB_TEXT
|
||||
#define SUB_TEXT(name) \
|
||||
protected: \
|
||||
text::Text *name##_text_{nullptr}; \
|
||||
\
|
||||
public: \
|
||||
void set_##name##_text(text::Text *text) { this->name##_text_ = text; }
|
||||
#endif
|
||||
|
||||
class KT0803Component : public PollingComponent, public i2c::I2CDevice {
|
||||
ChipId chip_id_; // no way to detect it
|
||||
bool reset_;
|
||||
union {
|
||||
struct KT0803State state_;
|
||||
uint8_t regs_[sizeof(struct KT0803State)];
|
||||
};
|
||||
|
||||
bool check_reg_(uint8_t addr);
|
||||
void write_reg_(uint8_t addr);
|
||||
bool read_reg_(uint8_t addr);
|
||||
|
||||
SUB_BINARY_SENSOR(pw_ok)
|
||||
SUB_BINARY_SENSOR(slncid)
|
||||
SUB_NUMBER(frequency)
|
||||
|
||||
void publish_pw_ok();
|
||||
void publish_slncid();
|
||||
void publish_frequency();
|
||||
|
||||
void publish(sensor::Sensor *s, float state);
|
||||
void publish(binary_sensor::BinarySensor *s, bool state);
|
||||
void publish(text_sensor::TextSensor *s, const std::string &state);
|
||||
void publish(number::Number *n, float state);
|
||||
void publish(switch_::Switch *s, bool state);
|
||||
void publish(select::Select *s, size_t index);
|
||||
void publish(text::Text *t, const std::string &state);
|
||||
|
||||
public:
|
||||
KT0803Component();
|
||||
|
||||
// float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
||||
void setup() override;
|
||||
void dump_config() override;
|
||||
void update() override;
|
||||
void loop() override;
|
||||
|
||||
void set_chip_id(ChipId value);
|
||||
ChipId get_chip_id();
|
||||
std::string get_chip_string() const;
|
||||
|
||||
void set_frequency(float value); // MHz
|
||||
float get_frequency();
|
||||
};
|
||||
|
||||
} // namespace kt0803
|
||||
} // namespace esphome
|
398
esphome/components/kt0803/kt0803defs.h
Normal file
398
esphome/components/kt0803/kt0803defs.h
Normal file
|
@ -0,0 +1,398 @@
|
|||
#pragma once
|
||||
|
||||
namespace esphome {
|
||||
namespace kt0803 {
|
||||
|
||||
static float CHSEL_MIN = 70.0f;
|
||||
static float CHSEL_MAX = 108.0f;
|
||||
|
||||
static float PGA_MIN = -15;
|
||||
static float PGA_MAX = 12;
|
||||
|
||||
static float RFGAIN_MIN = 95.5f;
|
||||
static float RFGAIN_MAX = 108.0f;
|
||||
|
||||
enum class ChipId {
|
||||
KT0803,
|
||||
KT0803K,
|
||||
KT0803M,
|
||||
KT0803L,
|
||||
};
|
||||
|
||||
enum class PreEmphasis {
|
||||
PHTCNST_50US,
|
||||
PHTCNST_75US,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class PilotToneAmplitudeAdjustment {
|
||||
PLTADJ_LOW,
|
||||
PLTADJ_HIGH,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class BassBoostControl {
|
||||
BASS_DISABLED,
|
||||
BASS_5DB,
|
||||
BASS_11DB,
|
||||
BASS_17DB,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class AlcTimeSelection {
|
||||
ALC_TIME_25US,
|
||||
ALC_TIME_50US,
|
||||
ALC_TIME_75US,
|
||||
ALC_TIME_100US,
|
||||
ALC_TIME_125US,
|
||||
ALC_TIME_150US,
|
||||
ALC_TIME_175US,
|
||||
ALC_TIME_200US,
|
||||
ALC_TIME_50MS,
|
||||
ALC_TIME_100MS,
|
||||
ALC_TIME_150MS,
|
||||
ALC_TIME_200MS,
|
||||
ALC_TIME_250MS,
|
||||
ALC_TIME_300MS,
|
||||
ALC_TIME_350MS,
|
||||
ALC_TIME_40MS,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class SilenceDetectionLowThreshold {
|
||||
SLNCTHL_025MV,
|
||||
SLNCTHL_050MV,
|
||||
SLNCTHL_1MV,
|
||||
SLNCTHL_2MV,
|
||||
SLNCTHL_4MV,
|
||||
SLNCTHL_8MV,
|
||||
SLNCTHL_16MV,
|
||||
SLNCTHL_32MV,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class SilenceDetectionHighThreshold {
|
||||
SLNCTHH_050MV,
|
||||
SLNCTHH_1MV,
|
||||
SLNCTHH_2MV,
|
||||
SLNCTHH_4MV,
|
||||
SLNCTHH_8MV,
|
||||
SLNCTHH_16MV,
|
||||
SLNCTHH_32MV,
|
||||
SLNCTHH_64MV,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class SilenceDetectionHighLevelCounterThreshold {
|
||||
SLNCCNTHIGH_15,
|
||||
SLNCCNTHIGH_31,
|
||||
SLNCCNTHIGH_63,
|
||||
SLNCCNTHIGH_127,
|
||||
SLNCCNTHIGH_255,
|
||||
SLNCCNTHIGH_511,
|
||||
SLNCCNTHIGH_1023,
|
||||
SLNCCNTHIGH_2047,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class SilenceDetectionLowAndHighLevelDurationTime {
|
||||
SLNCTIME_50MS,
|
||||
SLNCTIME_100MS,
|
||||
SLNCTIME_200MS,
|
||||
SLNCTIME_400MS,
|
||||
SLNCTIME_1S,
|
||||
SLNCTIME_2S,
|
||||
SLNCTIME_4S,
|
||||
SLNCTIME_8S,
|
||||
SLNCTIME_16S,
|
||||
SLNCTIME_24S,
|
||||
SLNCTIME_32S,
|
||||
SLNCTIME_40S,
|
||||
SLNCTIME_48S,
|
||||
SLNCTIME_56S,
|
||||
SLNCTIME_60S,
|
||||
SLNCTIME_64S,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class AlcCompressedGainSetting {
|
||||
ALCCMPGAIN_N6DB,
|
||||
ALCCMPGAIN_N9DB,
|
||||
ALCCMPGAIN_N12DB,
|
||||
ALCCMPGAIN_N15DB,
|
||||
ALCCMPGAIN_6DB,
|
||||
ALCCMPGAIN_3DB,
|
||||
ALCCMPGAIN_0DB,
|
||||
ALCCMPGAIN_N3DB,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class SilenceLowCounter {
|
||||
SLNCCNTLOW_1,
|
||||
SLNCCNTLOW_2,
|
||||
SLNCCNTLOW_4,
|
||||
SLNCCNTLOW_8,
|
||||
SLNCCNTLOW_16,
|
||||
SLNCCNTLOW_32,
|
||||
SLNCCNTLOW_64,
|
||||
SLNCCNTLOW_128,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class FrequencyDeviationAdjustment {
|
||||
FDEV_75KHZ,
|
||||
FDEV_112K5HZ,
|
||||
FDEV_150KHZ,
|
||||
FDEV_187K5HZ,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class XtalSelection {
|
||||
XTAL_SEL_32K768HZ,
|
||||
XTAL_SEL_7M6HZ,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class ReferenceClockSelection {
|
||||
REF_CLK_32K768HZ,
|
||||
REF_CLK_6M5HZ,
|
||||
REF_CLK_7M6HZ,
|
||||
REF_CLK_12MHZ,
|
||||
REF_CLK_13MHZ,
|
||||
REF_CLK_15M2HZ,
|
||||
REF_CLK_19M2HZ,
|
||||
REF_CLK_24MHZ,
|
||||
REF_CLK_26MHZ,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class AlcHighThresholdSelection {
|
||||
ALCHIGHTH_50MS,
|
||||
ALCHIGHTH_100MS,
|
||||
ALCHIGHTH_150MS,
|
||||
ALCHIGHTH_200MS,
|
||||
ALCHIGHTH_1S,
|
||||
ALCHIGHTH_5S,
|
||||
ALCHIGHTH_10S,
|
||||
ALCHIGHTH_15S,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class AlcHoldTimeSelection {
|
||||
ALCHOLD_06,
|
||||
ALCHOLD_05,
|
||||
ALCHOLD_04,
|
||||
ALCHOLD_03,
|
||||
ALCHOLD_02,
|
||||
ALCHOLD_01,
|
||||
ALCHOLD_005,
|
||||
ALCHOLD_001,
|
||||
LAST,
|
||||
};
|
||||
|
||||
enum class AlcLowThreshold {
|
||||
ALCLOWTH_025,
|
||||
ALCLOWTH_020,
|
||||
ALCLOWTH_015,
|
||||
ALCLOWTH_010,
|
||||
ALCLOWTH_005,
|
||||
ALCLOWTH_003,
|
||||
ALCLOWTH_002,
|
||||
ALCLOWTH_001,
|
||||
ALCLOWTH_0005,
|
||||
ALCLOWTH_0001,
|
||||
ALCLOWTH_00005,
|
||||
ALCLOWTH_00001,
|
||||
LAST,
|
||||
};
|
||||
|
||||
// 0 = KT0803
|
||||
// K = KT0803K or KT0803M (not datasheet for M, it should be mostly the same as K)
|
||||
// L = KT0803L
|
||||
|
||||
struct KT0803State {
|
||||
union {
|
||||
uint8_t REG_00;
|
||||
struct {
|
||||
uint8_t CHSEL1 : 8; // 0 K L
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_01;
|
||||
struct {
|
||||
uint8_t CHSEL2 : 3; // 0 K L
|
||||
uint8_t PGA : 3; // 0 K L
|
||||
uint8_t RFGAIN0 : 2; // 0 K L
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_02;
|
||||
struct {
|
||||
uint8_t PHTCNST : 1; // 0 K L
|
||||
uint8_t _02_1 : 1;
|
||||
uint8_t PLTADJ : 1; // 0 K L
|
||||
uint8_t MUTE : 1; // 0 K L
|
||||
uint8_t _02_2 : 2;
|
||||
uint8_t RFGAIN2 : 1; // 0 K L
|
||||
uint8_t CHSEL0 : 1; // K L (no LSB on 0, step size is only 100KHz)
|
||||
};
|
||||
};
|
||||
uint8_t REG_03;
|
||||
union {
|
||||
uint8_t REG_04;
|
||||
struct {
|
||||
uint8_t BASS : 2; // K L
|
||||
uint8_t FDEV_K : 2; // K
|
||||
uint8_t PGA_LSB : 2; // K L
|
||||
uint8_t MONO : 1; // K L
|
||||
uint8_t ALC_EN : 1; // L
|
||||
};
|
||||
};
|
||||
uint8_t REG_05;
|
||||
uint8_t REG_06;
|
||||
uint8_t REG_07;
|
||||
uint8_t REG_08;
|
||||
uint8_t REG_09;
|
||||
uint8_t REG_0A;
|
||||
union {
|
||||
uint8_t REG_0B;
|
||||
struct {
|
||||
uint8_t _0B_1 : 2;
|
||||
uint8_t AUTO_PADN : 1; // L
|
||||
uint8_t _0B_2 : 2;
|
||||
uint8_t PDPA : 1; // K L
|
||||
uint8_t _0B_3 : 1;
|
||||
uint8_t Standby : 1; // L
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_0C;
|
||||
struct {
|
||||
uint8_t ALC_ATTACK_TIME : 4; // L
|
||||
uint8_t ALC_DECAY_TIME : 4; // L
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_0E;
|
||||
struct {
|
||||
uint8_t _0E_1 : 1;
|
||||
uint8_t PA_BIAS : 1; // K L
|
||||
uint8_t _0E_2 : 6;
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_0F;
|
||||
struct {
|
||||
uint8_t _0F_1 : 2;
|
||||
uint8_t SLNCID : 1; // K L (ro)
|
||||
uint8_t _0F_2 : 1;
|
||||
uint8_t PW_OK : 1; // K L (ro)
|
||||
uint8_t _0F_3 : 3;
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_10;
|
||||
struct {
|
||||
uint8_t PGAMOD : 1; // K L
|
||||
uint8_t _10_1 : 2;
|
||||
uint8_t LMTLVL : 2; // K
|
||||
uint8_t _10_2 : 4;
|
||||
};
|
||||
};
|
||||
uint8_t REG_11;
|
||||
union {
|
||||
uint8_t REG_12;
|
||||
struct {
|
||||
uint8_t SW_MOD : 1; // K L
|
||||
uint8_t SLNCTHH : 3; // K L
|
||||
uint8_t SLNCTHL : 3; // K L
|
||||
uint8_t SLNCDIS : 1; // K L
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_13;
|
||||
struct {
|
||||
uint8_t _13_1 : 2;
|
||||
uint8_t PA_CTRL : 1; // 0 K L
|
||||
uint8_t _13_2 : 4;
|
||||
uint8_t RFGAIN1 : 1; // 0 K L
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_14;
|
||||
struct {
|
||||
uint8_t SLNCTIME_MSB : 1; // L
|
||||
uint8_t _14_1 : 1;
|
||||
uint8_t SLNCCNTHIGH : 3; // K L
|
||||
uint8_t SLNCTIME : 3; // K L
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_15;
|
||||
struct {
|
||||
uint8_t _15_1 : 5;
|
||||
uint8_t ALCCMPGAIN : 3; // L
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_16;
|
||||
struct {
|
||||
uint8_t SLNCCNTLOW : 3; // K L
|
||||
uint8_t _16_1 : 5;
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_17;
|
||||
struct {
|
||||
uint8_t _17_1 : 3;
|
||||
uint8_t XTAL_SEL : 1; // L
|
||||
uint8_t _17_2 : 1;
|
||||
uint8_t AU_ENHANCE : 1; // L
|
||||
uint8_t FDEV_L : 1; // L
|
||||
uint8_t _17_3 : 1;
|
||||
};
|
||||
};
|
||||
uint8_t REG_18;
|
||||
uint8_t REG_19;
|
||||
uint8_t REG_1A;
|
||||
uint8_t REG_1B;
|
||||
uint8_t REG_1C;
|
||||
uint8_t REG_1D;
|
||||
union {
|
||||
uint8_t REG_1E;
|
||||
struct {
|
||||
uint8_t _1E_1 : 1;
|
||||
uint8_t REF_CLK : 3; // L
|
||||
uint8_t _1E_2 : 1;
|
||||
uint8_t XTALD : 1; // L
|
||||
uint8_t DCLK : 1; // L
|
||||
uint8_t _1E_3 : 1;
|
||||
};
|
||||
};
|
||||
uint8_t REG_1F;
|
||||
uint8_t REG_20;
|
||||
uint8_t REG_21;
|
||||
uint8_t REG_22;
|
||||
uint8_t REG_23;
|
||||
uint8_t REG_24;
|
||||
uint8_t REG_25;
|
||||
union {
|
||||
uint8_t REG_26;
|
||||
struct {
|
||||
uint8_t _26_1 : 1;
|
||||
uint8_t ALCHIGHTH : 3; // L
|
||||
uint8_t _26_2 : 1;
|
||||
uint8_t ALCHOLD : 3; // L
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint8_t REG_27;
|
||||
struct {
|
||||
uint8_t ALCLOWTH : 4; // L
|
||||
uint8_t _27_1 : 4;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace kt0803
|
||||
} // namespace esphome
|
38
esphome/components/kt0803/number/__init__.py
Normal file
38
esphome/components/kt0803/number/__init__.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
import esphome.codegen as cg
|
||||
from esphome.components import number
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_FREQUENCY,
|
||||
DEVICE_CLASS_FREQUENCY,
|
||||
ENTITY_CATEGORY_CONFIG,
|
||||
)
|
||||
from .. import (
|
||||
CONF_KT0803_ID,
|
||||
KT0803Component,
|
||||
kt0803_ns,
|
||||
UNIT_MEGA_HERTZ,
|
||||
)
|
||||
|
||||
FrequencyNumber = kt0803_ns.class_("FrequencyNumber", number.Number)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_KT0803_ID): cv.use_id(KT0803Component),
|
||||
cv.Optional(CONF_FREQUENCY): number.number_schema(
|
||||
FrequencyNumber,
|
||||
unit_of_measurement=UNIT_MEGA_HERTZ,
|
||||
device_class=DEVICE_CLASS_FREQUENCY,
|
||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
kt0803_component = await cg.get_variable(config[CONF_KT0803_ID])
|
||||
if frequency_config := config.get(CONF_FREQUENCY):
|
||||
n = await number.new_number(
|
||||
frequency_config, min_value=70, max_value=108, step=0.05
|
||||
)
|
||||
await cg.register_parented(n, config[CONF_KT0803_ID])
|
||||
cg.add(kt0803_component.set_frequency_number(n))
|
12
esphome/components/kt0803/number/frequency_number.cpp
Normal file
12
esphome/components/kt0803/number/frequency_number.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "frequency_number.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace kt0803 {
|
||||
|
||||
void FrequencyNumber::control(float value) {
|
||||
this->publish_state(value);
|
||||
this->parent_->set_frequency(value);
|
||||
}
|
||||
|
||||
} // namespace kt0803
|
||||
} // namespace esphome
|
18
esphome/components/kt0803/number/frequency_number.h
Normal file
18
esphome/components/kt0803/number/frequency_number.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "esphome/components/number/number.h"
|
||||
#include "../kt0803.h"
|
||||
|
||||
namespace esphome {
|
||||
namespace kt0803 {
|
||||
|
||||
class FrequencyNumber : public number::Number, public Parented<KT0803Component> {
|
||||
public:
|
||||
FrequencyNumber() = default;
|
||||
|
||||
protected:
|
||||
void control(float value) override;
|
||||
};
|
||||
|
||||
} // namespace kt0803
|
||||
} // namespace esphome
|
Loading…
Add table
Reference in a new issue