mirror of
https://github.com/esphome/esphome.git
synced 2024-11-28 01:34:18 +01:00
config done
This commit is contained in:
parent
b695d1e804
commit
58f63e38be
61 changed files with 2612 additions and 417 deletions
|
@ -22,6 +22,8 @@ UNIT_KILO_HERTZ = "kHz"
|
||||||
UNIT_MILLI_VOLT = "mV"
|
UNIT_MILLI_VOLT = "mV"
|
||||||
UNIT_MICRO_AMPERE = "mA"
|
UNIT_MICRO_AMPERE = "mA"
|
||||||
UNIT_DECIBEL_MICRO_VOLT = "dBµV"
|
UNIT_DECIBEL_MICRO_VOLT = "dBµV"
|
||||||
|
UNIT_PICO_FARAD = "pF"
|
||||||
|
UNIT_KILO_OHM = "kOhm"
|
||||||
|
|
||||||
ICON_VOLUME_MUTE = "mdi:volume-mute"
|
ICON_VOLUME_MUTE = "mdi:volume-mute"
|
||||||
ICON_EAR_HEARING = "mdi:ear-hearing"
|
ICON_EAR_HEARING = "mdi:ear-hearing"
|
||||||
|
@ -38,55 +40,244 @@ Si4713Component = si4713_ns.class_(
|
||||||
|
|
||||||
CONF_SI4713_ID = "si4713_id"
|
CONF_SI4713_ID = "si4713_id"
|
||||||
CONF_RESET_PIN = "reset_pin"
|
CONF_RESET_PIN = "reset_pin"
|
||||||
CONF_FREQUENCY_DEVIATION = "frequency_deviation"
|
CONF_CHIP_ID = "chip_id"
|
||||||
|
CONF_SECTION_TUNER = "tuner"
|
||||||
|
CONF_SECTION_ANALOG = "analog"
|
||||||
|
CONF_SECTION_DIGITAL = "digital"
|
||||||
|
CONF_SECTION_PILOT = "pilot"
|
||||||
|
CONF_SECTION_REFCLK = "refclk"
|
||||||
|
CONF_SECTION_COMPRESSOR = "compressor"
|
||||||
|
CONF_SECTION_LIMITER = "limiter"
|
||||||
|
CONF_SECTION_ASQ = "asq"
|
||||||
|
CONF_SECTION_RDS = "rds"
|
||||||
|
CONF_SECTION_OUTPUT = "output"
|
||||||
|
# general config
|
||||||
|
CONF_OP_MODE = "op_mode"
|
||||||
CONF_MUTE = "mute"
|
CONF_MUTE = "mute"
|
||||||
CONF_MONO = "mono"
|
CONF_MONO = "mono"
|
||||||
CONF_TX_ENABLE = "tx_enable"
|
|
||||||
CONF_TX_PILOT = "tx_pilot"
|
|
||||||
CONF_T1M_SEL = "t1m_sel"
|
|
||||||
CONF_PRIV_EN = "priv_en"
|
|
||||||
CONF_PRE_EMPHASIS = "pre_emphasis"
|
CONF_PRE_EMPHASIS = "pre_emphasis"
|
||||||
CONF_XTAL_SOURCE = "xtal_source"
|
# tuner
|
||||||
CONF_XTAL_CURRENT = "xtal_current"
|
CONF_FREQUENCY = "frequency"
|
||||||
CONF_XTAL_FREQUENCY = "xtal_frequency"
|
CONF_DEVIATION = "deviation"
|
||||||
CONF_INPUT_IMPEDANCE = "input_impedance"
|
CONF_POWER = "power"
|
||||||
CONF_INPUT_GAIN = "input_gain"
|
CONF_ANTCAP = "antcap"
|
||||||
CONF_DIGITAL_GAIN = "digital_gain"
|
# analog
|
||||||
CONF_POWER_TARGET = "power_target"
|
CONF_LEVEL = "level"
|
||||||
CONF_RDS_ENABLE = "rds_enable"
|
CONF_ATTENUATION = "attenuation"
|
||||||
CONF_RDS_FREQUENCY_DEVIATION = "rds_frequency_deviation"
|
# digital
|
||||||
CONF_RDS_STATION = "rds_station"
|
CONF_SAMPLE_RATE = "sample_rate"
|
||||||
CONF_RDS_TEXT = "rds_text"
|
CONF_SAMPLE_BITS = "sample_bits"
|
||||||
CONF_AUD_PK = "aud_pk"
|
CONF_CHANNELS = "channels"
|
||||||
CONF_FSM = "fsm"
|
CONF_MODE = "mode"
|
||||||
CONF_CHIP_ID = "chip_id"
|
CONF_CLOCK_EDGE = "clock_edge"
|
||||||
CONF_REG30 = "reg30"
|
# pilot
|
||||||
|
CONF_ENABLE = "enable"
|
||||||
|
CONF_FREQUENCY = "frequency"
|
||||||
|
CONF_DEVIATION = "deviation"
|
||||||
|
# refclk
|
||||||
|
CONF_FREQUENCY = "frequency"
|
||||||
|
CONF_SOURCE = "source"
|
||||||
|
CONF_PRESCALER = "prescaler"
|
||||||
|
# compressor
|
||||||
|
CONF_ENABLE = "enable"
|
||||||
|
CONF_THRESHOLD = "threshold"
|
||||||
|
CONF_ATTACK = "attack"
|
||||||
|
CONF_RELEASE = "release"
|
||||||
|
CONF_GAIN = "gain"
|
||||||
|
CONF_PRESET = "preset"
|
||||||
|
# limiter
|
||||||
|
CONF_ENABLE = "enable"
|
||||||
|
CONF_RELEASE_TIME = "release_time"
|
||||||
|
# asq
|
||||||
|
CONF_OVERMOD = "overmod"
|
||||||
|
CONF_IALL = "iall"
|
||||||
|
CONF_IALH = "ialh"
|
||||||
|
CONF_LEVEL_LOW = "level_low"
|
||||||
|
CONF_DURATION_LOW = "duration_low"
|
||||||
|
CONF_LEVEL_HIGH = "level_high"
|
||||||
|
CONF_DURATION_HIGH = "duration_high"
|
||||||
|
# rds
|
||||||
|
CONF_ENABLE = "enable"
|
||||||
|
CONF_DEVIATION = "deviation"
|
||||||
|
CONF_STATION = "station"
|
||||||
|
CONF_TEXT = "text"
|
||||||
|
# output
|
||||||
|
CONF_GPIO1="gpio1"
|
||||||
|
CONF_GPIO2="gpio2"
|
||||||
|
CONF_GPIO3="gpio3"
|
||||||
|
|
||||||
SetFrequencyAction = si4713_ns.class_(
|
SetFrequencyAction = si4713_ns.class_(
|
||||||
"SetFrequencyAction", automation.Action, cg.Parented.template(Si4713Component)
|
"SetFrequencyAction", automation.Action, cg.Parented.template(Si4713Component)
|
||||||
)
|
)
|
||||||
|
|
||||||
#T1mSel = si4713_ns.enum("T1mSel", True)
|
OpMode = si4713_ns.enum("OpMode", True)
|
||||||
#T1M_SEL = {
|
OP_MODE = {
|
||||||
# "58s": T1mSel.T1M_SEL_58S,
|
"Analog": OpMode.OPMODE_ANALOG,
|
||||||
# "59s": T1mSel.T1M_SEL_59S,
|
"Digital": OpMode.OPMODE_Digital,
|
||||||
# "60s": T1mSel.T1M_SEL_60S,
|
}
|
||||||
# "Never": T1mSel.T1M_SEL_NEVER,
|
|
||||||
#}
|
|
||||||
|
|
||||||
|
PreEmphasis = si4713_ns.enum("PreEmphasis", True)
|
||||||
|
PRE_EMPHASIS = {
|
||||||
|
"75us": PreEmphasis.FMPE_75US,
|
||||||
|
"50us": PreEmphasis.FMPE_50US,
|
||||||
|
"Disabled": PreEmphasis.FMPE_DISABLED,
|
||||||
|
}
|
||||||
|
|
||||||
|
LineAttenuation = si4713_ns.enum("LineAttenuation", True)
|
||||||
|
LINE_ATTENUATION = {
|
||||||
|
"396kOhm": LineAttenuation.LIATTEN_396KOHM,
|
||||||
|
"100kOhm": LineAttenuation.LIATTEN_100KOHM,
|
||||||
|
"74kOhm": LineAttenuation.LIATTEN_74KOHM,
|
||||||
|
"60kOhm": LineAttenuation.LIATTEN_60KOHM,
|
||||||
|
}
|
||||||
|
|
||||||
|
SampleBits = si4713_ns.enum("SampleBits", True)
|
||||||
|
SAMPLE_BITS = {
|
||||||
|
"16": SampleBits.ISIZE_16BITS,
|
||||||
|
"20": SampleBits.ISIZE_20BITS,
|
||||||
|
"24": SampleBits.ISIZE_24BITS,
|
||||||
|
"8": SampleBits.ISIZE_8BITS,
|
||||||
|
}
|
||||||
|
|
||||||
|
SampleChannels = si4713_ns.enum("SampleChannels", True)
|
||||||
|
SAMPLE_CHANNELS = {
|
||||||
|
"Stereo": SampleChannels.IMONO_STEREO,
|
||||||
|
"Mono": SampleChannels.IMONO_MONO,
|
||||||
|
}
|
||||||
|
|
||||||
|
DigitalMode = si4713_ns.enum("DigitalMode", True)
|
||||||
|
DIGITAL_MODE = {
|
||||||
|
"Default": DigitalMode.IMODE_DEFAULT,
|
||||||
|
"I2S": DigitalMode.IMODE_I2S,
|
||||||
|
"Left Justified": DigitalMode.IMODE_LEFT_JUSTIFIED,
|
||||||
|
"MSB at 1st": DigitalMode.IMODE_MSB_AT_1ST,
|
||||||
|
"MSB at 2nd": DigitalMode.IMODE_MSB_AT_2ND,
|
||||||
|
}
|
||||||
|
|
||||||
|
DigitalClockEdge = si4713_ns.enum("DigitalClockEdge", True)
|
||||||
|
DIGITAL_CLOCK_EDGE = {
|
||||||
|
"Rising": DigitalClockEdge.IFALL_DCLK_RISING_EDGE,
|
||||||
|
"Falling": DigitalClockEdge.IFALL_DCLK_FALLING_EDGE,
|
||||||
|
}
|
||||||
|
|
||||||
|
RefClkSource = si4713_ns.enum("RefClkSource", True)
|
||||||
|
REFCLK_SOURCE = {
|
||||||
|
"RCLK": RefClkSource.RCLKSEL_RCLK,
|
||||||
|
"DCLK": RefClkSource.RCLKSEL_DCLK,
|
||||||
|
}
|
||||||
|
|
||||||
|
AcompAttack = si4713_ns.enum("AcompAttack", True)
|
||||||
|
ACOMP_ATTACK = {
|
||||||
|
"0.5ms": AcompAttack.ATTACK_05MS,
|
||||||
|
"1.0ms": AcompAttack.ATTACK_10MS,
|
||||||
|
"1.5ms": AcompAttack.ATTACK_15MS,
|
||||||
|
"2.0ms": AcompAttack.ATTACK_20MS,
|
||||||
|
"2.5ms": AcompAttack.ATTACK_25MS,
|
||||||
|
"3.0ms": AcompAttack.ATTACK_30MS,
|
||||||
|
"3.5ms": AcompAttack.ATTACK_35MS,
|
||||||
|
"4.0ms": AcompAttack.ATTACK_40MS,
|
||||||
|
"4.5ms": AcompAttack.ATTACK_45MS,
|
||||||
|
"5.0ms": AcompAttack.ATTACK_50MS,
|
||||||
|
}
|
||||||
|
|
||||||
|
AcompRelease = si4713_ns.enum("AcompRelease", True)
|
||||||
|
ACOMP_RELEASE = {
|
||||||
|
"100ms": AcompRelease.RELEASE_100MS,
|
||||||
|
"200ms": AcompRelease.RELEASE_200MS,
|
||||||
|
"350ms": AcompRelease.RELEASE_350MS,
|
||||||
|
"525ms": AcompRelease.RELEASE_525MS,
|
||||||
|
"1000ms": AcompRelease.RELEASE_1000MS,
|
||||||
|
}
|
||||||
|
|
||||||
|
AcompPreset = si4713_ns.enum("AcompPreset", True)
|
||||||
|
ACOMP_PRESET = {
|
||||||
|
"Minimal": AcompPreset.ACOMP_MINIMAL,
|
||||||
|
"Aggressive": AcompPreset.ACOMP_AGGRESSIVE,
|
||||||
|
"Custom": AcompPreset.ACOMP_CUSTOM,
|
||||||
|
}
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = (
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(Si4713Component),
|
cv.GenerateID(): cv.declare_id(Si4713Component),
|
||||||
cv.Required(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
cv.Required(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
||||||
cv.Optional(CONF_FREQUENCY, default=87.50): cv.float_range(76, 108),
|
cv.Optional(CONF_OP_MODE, default="Analog"): cv.enum(OP_MODE),
|
||||||
cv.Optional(CONF_MUTE, default=False): cv.boolean,
|
cv.Optional(CONF_MUTE, default=False): cv.boolean,
|
||||||
cv.Optional(CONF_MONO, default=False): cv.boolean,
|
cv.Optional(CONF_MONO, default=False): cv.boolean,
|
||||||
# cv.Optional(CONF_T1M_SEL, default="60s"): cv.enum(T1M_SEL),
|
cv.Optional(CONF_PRE_EMPHASIS, default="75us"): cv.enum(PRE_EMPHASIS),
|
||||||
cv.Optional(CONF_RDS_ENABLE, default=False): cv.boolean,
|
cv.Optional(CONF_SECTION_TUNER): cv.Schema(
|
||||||
cv.Optional(CONF_RDS_STATION): cv.string,
|
{
|
||||||
cv.Optional(CONF_RDS_TEXT): cv.string,
|
cv.Optional(CONF_FREQUENCY, default=87.50): cv.float_range(76, 108), # MHz
|
||||||
|
cv.Optional(CONF_DEVIATION, default=68.25): cv.float_range(0, 90), # kHz
|
||||||
|
cv.Optional(CONF_POWER, default=115): cv.int_range(88, 115),
|
||||||
|
cv.Optional(CONF_ANTCAP, default=0): cv.int_range(0, 191),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_ANALOG): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_LEVEL, default=636): cv.int_range(0, 1023),
|
||||||
|
cv.Optional(CONF_ATTENUATION, default=636): cv.enum(LINE_ATTENUATION),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_DIGITAL): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_SAMPLE_RATE, default=44100): cv.int_range(32000, 48000), # Hz
|
||||||
|
cv.Optional(CONF_SAMPLE_BITS, default="16"): cv.enum(SAMPLE_BITS),
|
||||||
|
cv.Optional(CONF_CHANNELS, default="Stereo"): cv.enum(SAMPLE_CHANNELS),
|
||||||
|
cv.Optional(CONF_MODE, default="Default"): cv.enum(DIGITAL_MODE),
|
||||||
|
cv.Optional(CONF_CLOCK_EDGE, default="Rising"): cv.enum(DIGITAL_CLOCK_EDGE),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_PILOT): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ENABLE, default="True"): cv.boolean,
|
||||||
|
cv.Optional(CONF_FREQUENCY, default=19): cv.float_range(0, 19), # kHz
|
||||||
|
cv.Optional(CONF_DEVIATION, default=6.75): cv.float_range(0, 90), # kHz
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_REFCLK): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_FREQUENCY, default=32768): cv.int_range(31130, 34406), # Hz
|
||||||
|
cv.Optional(CONF_SOURCE, default="RCLK"): cv.enum(REFCLK_SOURCE),
|
||||||
|
cv.Optional(CONF_PRESCALER, default=1): cv.int_range(0, 4095),
|
||||||
|
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_COMPRESSOR): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ENABLE, default="False"): cv.boolean,
|
||||||
|
cv.Optional(CONF_THRESHOLD, default=-40): cv.int_range(-40, 0),
|
||||||
|
cv.Optional(CONF_ATTACK, default='0.5'): cv.enum(ACOMP_ATTACK),
|
||||||
|
cv.Optional(CONF_RELEASE, default="1000"): cv.enum(ACOMP_RELEASE),
|
||||||
|
cv.Optional(CONF_GAIN, default=15): cv.int_range(0, 20),
|
||||||
|
cv.Optional(CONF_PRESET, default="Custom"): cv.enum(ACOMP_PRESET),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_LIMITER): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ENABLE, default="True"): cv.boolean,
|
||||||
|
cv.Optional(CONF_RELEASE_TIME, default=5): cv.float_range(0.25, 102.4),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_ASQ): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_OVERMOD, default="False"): cv.boolean,
|
||||||
|
cv.Optional(CONF_IALL, default="False"): cv.boolean,
|
||||||
|
cv.Optional(CONF_IALH, default="False"): cv.boolean,
|
||||||
|
cv.Optional(CONF_LEVEL_LOW, default=0): cv.float_range(-70, 0),
|
||||||
|
cv.Optional(CONF_DURATION_LOW, default=0): cv.int_range(0, 65535),
|
||||||
|
cv.Optional(CONF_LEVEL_HIGH, default=0): cv.float_range(-70, 0),
|
||||||
|
cv.Optional(CONF_DURATION_HIGH, default=0): cv.int_range(0, 65535),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_RDS): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ENABLE, default=False): cv.boolean,
|
||||||
|
cv.Optional(CONF_DEVIATION, default=2.0): cv.float_range(0, 7.5), # kHz
|
||||||
|
cv.Optional(CONF_STATION): cv.string,
|
||||||
|
cv.Optional(CONF_TEXT): cv.string,
|
||||||
|
}
|
||||||
|
),
|
||||||
cv.Optional(CONF_CHIP_ID): text_sensor.text_sensor_schema(
|
cv.Optional(CONF_CHIP_ID): text_sensor.text_sensor_schema(
|
||||||
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
icon=ICON_CHIP,
|
icon=ICON_CHIP,
|
||||||
|
@ -103,13 +294,13 @@ async def set_var(config, id, setter):
|
||||||
cg.add(setter(c))
|
cg.add(setter(c))
|
||||||
|
|
||||||
|
|
||||||
async def set_sensor(config, id, setter):
|
async def new_sensor(config, id, setter):
|
||||||
if c := config.get(id):
|
if c := config.get(id):
|
||||||
s = await sensor.new_sensor(c)
|
s = await sensor.new_sensor(c)
|
||||||
cg.add(setter(s))
|
cg.add(setter(s))
|
||||||
|
|
||||||
|
|
||||||
async def set_text_sensor(config, id, setter):
|
async def new_text_sensor(config, id, setter):
|
||||||
if c := config.get(id):
|
if c := config.get(id):
|
||||||
s = await text_sensor.new_text_sensor(c)
|
s = await text_sensor.new_text_sensor(c)
|
||||||
cg.add(setter(s))
|
cg.add(setter(s))
|
||||||
|
@ -121,11 +312,53 @@ async def to_code(config):
|
||||||
await i2c.register_i2c_device(var, config)
|
await i2c.register_i2c_device(var, config)
|
||||||
reset_pin = await cg.gpio_pin_expression(config[CONF_RESET_PIN])
|
reset_pin = await cg.gpio_pin_expression(config[CONF_RESET_PIN])
|
||||||
cg.add(var.set_reset_pin(reset_pin))
|
cg.add(var.set_reset_pin(reset_pin))
|
||||||
await set_var(config, CONF_FREQUENCY, var.set_frequency)
|
await set_var(config, CONF_OP_MODE, var.set_op_mode)
|
||||||
await set_var(config, CONF_MUTE, var.set_mute)
|
await set_var(config, CONF_MUTE, var.set_mute)
|
||||||
await set_var(config, CONF_MONO, var.set_mono)
|
await set_var(config, CONF_MONO, var.set_mono)
|
||||||
# await set_var(config, CONF_T1M_SEL, var.set_t1m_sel)
|
await set_var(config, CONF_PRE_EMPHASIS, var.set_pre_emphasis)
|
||||||
await set_var(config, CONF_RDS_ENABLE, var.set_rds_enable)
|
if tuner_config := config.get(CONF_SECTION_TUNER):
|
||||||
await set_var(config, CONF_RDS_STATION, var.set_rds_station)
|
await set_var(tuner_config, CONF_FREQUENCY, var.set_frequency)
|
||||||
await set_var(config, CONF_RDS_TEXT, var.set_rds_text)
|
await set_var(tuner_config, CONF_DEVIATION, var.set_audio_deviation)
|
||||||
await set_text_sensor(config, CONF_CHIP_ID, var.set_chip_id_text_sensor)
|
await set_var(tuner_config, CONF_POWER, var.set_power)
|
||||||
|
await set_var(tuner_config, CONF_ANTCAP, var.set_antcap)
|
||||||
|
if analog_config := config.get(CONF_SECTION_ANALOG):
|
||||||
|
await set_var(analog_config, CONF_LEVEL, var.set_analog_level)
|
||||||
|
await set_var(analog_config, CONF_ATTENUATION, var.set_analog_attenuation)
|
||||||
|
if digital_config := config.get(CONF_SECTION_DIGITAL):
|
||||||
|
await set_var(digital_config, CONF_SAMPLE_RATE, var.set_digital_sample_rate)
|
||||||
|
await set_var(digital_config, CONF_SAMPLE_BITS, var.set_digital_sample_bits)
|
||||||
|
await set_var(digital_config, CONF_CHANNELS, var.set_digital_channels)
|
||||||
|
await set_var(digital_config, CONF_MODE, var.set_digital_mode)
|
||||||
|
await set_var(digital_config, CONF_CLOCK_EDGE, var.set_digital_clock_edge)
|
||||||
|
if pilot_config := config.get(CONF_SECTION_PILOT):
|
||||||
|
await set_var(pilot_config, CONF_ENABLE, var.set_pilot_enable)
|
||||||
|
await set_var(pilot_config, CONF_FREQUENCY, var.set_pilot_frequency)
|
||||||
|
await set_var(pilot_config, CONF_DEVIATION, var.set_pilot_deviation)
|
||||||
|
if refclk_config := config.get(CONF_SECTION_REFCLK):
|
||||||
|
await set_var(refclk_config, CONF_FREQUENCY, var.set_refclk_frequency)
|
||||||
|
await set_var(refclk_config, CONF_SOURCE, var.set_refclk_source)
|
||||||
|
await set_var(refclk_config, CONF_PRESCALER, var.set_refclk_prescaler)
|
||||||
|
if compressor_config := config.get(CONF_SECTION_COMPRESSOR):
|
||||||
|
await set_var(compressor_config, CONF_ENABLE, var.set_acomp_enable)
|
||||||
|
await set_var(compressor_config, CONF_THRESHOLD, var.set_acomp_threshold)
|
||||||
|
await set_var(compressor_config, CONF_ATTACK, var.set_acomp_attack)
|
||||||
|
await set_var(compressor_config, CONF_RELEASE, var.set_acomp_release)
|
||||||
|
await set_var(compressor_config, CONF_GAIN, var.set_acomp_gain)
|
||||||
|
await set_var(compressor_config, CONF_PRESET, var.set_acomp_preset)
|
||||||
|
if limiter_config := config.get(CONF_SECTION_LIMITER):
|
||||||
|
await set_var(limiter_config, CONF_ENABLE, var.set_limiter_enable)
|
||||||
|
await set_var(limiter_config, CONF_RELEASE_TIME, var.set_limiter_release_time)
|
||||||
|
if asq_config := config.get(CONF_SECTION_ASQ):
|
||||||
|
await set_var(asq_config, CONF_OVERMOD, var.set_asq_overmod_enable)
|
||||||
|
await set_var(asq_config, CONF_IALL, var.set_asq_iall_enable)
|
||||||
|
await set_var(asq_config, CONF_IALH, var.set_asq_ialh_enable)
|
||||||
|
await set_var(asq_config, CONF_LEVEL_LOW, var.set_asq_level_low)
|
||||||
|
await set_var(asq_config, CONF_DURATION_LOW, var.set_asq_duration_low)
|
||||||
|
await set_var(asq_config, CONF_LEVEL_HIGH, var.set_asq_level_high)
|
||||||
|
await set_var(asq_config, CONF_DURATION_HIGH, var.set_asq_duration_high)
|
||||||
|
if rds_config := config.get(CONF_SECTION_RDS):
|
||||||
|
await set_var(rds_config, CONF_ENABLE, var.set_rds_enable)
|
||||||
|
await set_var(rds_config, CONF_DEVIATION, var.set_rds_deviation)
|
||||||
|
await set_var(rds_config, CONF_STATION, var.set_rds_station)
|
||||||
|
await set_var(rds_config, CONF_TEXT, var.set_rds_text)
|
||||||
|
await new_text_sensor(config, CONF_CHIP_ID, var.set_chip_id_text_sensor)
|
||||||
|
|
|
@ -3,11 +3,15 @@ from esphome.components import number
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
CONF_FREQUENCY,
|
CONF_FREQUENCY,
|
||||||
UNIT_PERCENT,
|
CONF_MODE,
|
||||||
|
UNIT_HERTZ,
|
||||||
|
UNIT_MILLISECOND,
|
||||||
UNIT_DECIBEL,
|
UNIT_DECIBEL,
|
||||||
|
UNIT_EMPTY,
|
||||||
DEVICE_CLASS_FREQUENCY,
|
DEVICE_CLASS_FREQUENCY,
|
||||||
DEVICE_CLASS_CURRENT,
|
DEVICE_CLASS_VOLTAGE,
|
||||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
|
DEVICE_CLASS_DURATION,
|
||||||
DEVICE_CLASS_EMPTY,
|
DEVICE_CLASS_EMPTY,
|
||||||
ENTITY_CATEGORY_CONFIG,
|
ENTITY_CATEGORY_CONFIG,
|
||||||
)
|
)
|
||||||
|
@ -15,37 +19,245 @@ from .. import (
|
||||||
CONF_SI4713_ID,
|
CONF_SI4713_ID,
|
||||||
Si4713Component,
|
Si4713Component,
|
||||||
si4713_ns,
|
si4713_ns,
|
||||||
# CONF_,
|
CONF_SECTION_TUNER,
|
||||||
|
CONF_SECTION_ANALOG,
|
||||||
|
CONF_SECTION_DIGITAL,
|
||||||
|
CONF_SECTION_PILOT,
|
||||||
|
CONF_SECTION_REFCLK,
|
||||||
|
CONF_SECTION_COMPRESSOR,
|
||||||
|
CONF_SECTION_LIMITER,
|
||||||
|
CONF_SECTION_ASQ,
|
||||||
|
CONF_SECTION_RDS,
|
||||||
|
CONF_FREQUENCY,
|
||||||
|
CONF_DEVIATION,
|
||||||
|
CONF_POWER,
|
||||||
|
CONF_ANTCAP,
|
||||||
|
CONF_LEVEL,
|
||||||
|
CONF_SAMPLE_RATE,
|
||||||
|
CONF_PRESCALER,
|
||||||
|
CONF_THRESHOLD,
|
||||||
|
CONF_GAIN,
|
||||||
|
CONF_RELEASE_TIME,
|
||||||
|
CONF_LEVEL_LOW,
|
||||||
|
CONF_DURATION_LOW,
|
||||||
|
CONF_LEVEL_HIGH,
|
||||||
|
CONF_DURATION_HIGH,
|
||||||
UNIT_MEGA_HERTZ,
|
UNIT_MEGA_HERTZ,
|
||||||
UNIT_KILO_HERTZ,
|
UNIT_KILO_HERTZ,
|
||||||
UNIT_MICRO_AMPERE,
|
UNIT_MILLI_VOLT,
|
||||||
UNIT_DECIBEL_MICRO_VOLT,
|
UNIT_DECIBEL_MICRO_VOLT,
|
||||||
|
UNIT_PICO_FARAD,
|
||||||
)
|
)
|
||||||
|
|
||||||
FrequencyNumber = si4713_ns.class_("FrequencyNumber", number.Number)
|
FrequencyNumber = si4713_ns.class_("FrequencyNumber", number.Number)
|
||||||
|
AudioDeviationNumber = si4713_ns.class_("AudioDeviationNumber", number.Number)
|
||||||
|
PowerNumber = si4713_ns.class_("PowerNumber", number.Number)
|
||||||
|
AntcapNumber = si4713_ns.class_("AntcapNumber", number.Number)
|
||||||
|
AnalogLevelNumber = si4713_ns.class_("AnalogLevelNumber", number.Number)
|
||||||
|
DigitalSampleRateNumber = si4713_ns.class_("DigitalSampleRateNumber", number.Number)
|
||||||
|
PilotFrequencyNumber = si4713_ns.class_("PilotFrequencyNumber", number.Number)
|
||||||
|
PilotDeviationNumber = si4713_ns.class_("PilotDeviationNumber", number.Number)
|
||||||
|
RefClkFrequencyNumber = si4713_ns.class_("RefClkFrequencyNumber", number.Number)
|
||||||
|
RefClkPrescalerNumber = si4713_ns.class_("RefClkPrescalerNumber", number.Number)
|
||||||
|
AcompThresholdNumber = si4713_ns.class_("AcompThresholdNumber", number.Number)
|
||||||
|
AcompGainNumber = si4713_ns.class_("AcompGainNumber", number.Number)
|
||||||
|
LimiterReleaseTimeNumber = si4713_ns.class_("LimiterReleaseTimeNumber", number.Number)
|
||||||
|
AsqLevelLowNumber = si4713_ns.class_("AsqLevelLowNumber", number.Number)
|
||||||
|
AsqDurationLowNumber = si4713_ns.class_("AsqDurationLowNumber", number.Number)
|
||||||
|
AsqLevelHighNumber = si4713_ns.class_("AsqLevelHighNumber", number.Number)
|
||||||
|
AsqDurationHighNumber = si4713_ns.class_("AsqDurationHighNumber", number.Number)
|
||||||
|
RdsDeviationNumber = si4713_ns.class_("RdsDeviationNumber", number.Number)
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.Schema(
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
|
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
|
||||||
|
cv.Optional(CONF_SECTION_TUNER): cv.Schema(
|
||||||
|
{
|
||||||
cv.Optional(CONF_FREQUENCY): number.number_schema(
|
cv.Optional(CONF_FREQUENCY): number.number_schema(
|
||||||
FrequencyNumber,
|
FrequencyNumber,
|
||||||
unit_of_measurement=UNIT_MEGA_HERTZ,
|
unit_of_measurement=UNIT_MEGA_HERTZ,
|
||||||
device_class=DEVICE_CLASS_FREQUENCY,
|
device_class=DEVICE_CLASS_FREQUENCY,
|
||||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_DEVIATION): number.number_schema(
|
||||||
|
AudioDeviationNumber,
|
||||||
|
unit_of_measurement=UNIT_KILO_HERTZ,
|
||||||
|
device_class=DEVICE_CLASS_FREQUENCY,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_POWER): number.number_schema(
|
||||||
|
PowerNumber,
|
||||||
|
unit_of_measurement=UNIT_DECIBEL_MICRO_VOLT,
|
||||||
|
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_ANTCAP): number.number_schema(
|
||||||
|
AntcapNumber,
|
||||||
|
unit_of_measurement=UNIT_PICO_FARAD,
|
||||||
|
device_class=DEVICE_CLASS_EMPTY,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_ANALOG): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_LEVEL): number.number_schema(
|
||||||
|
AnalogLevelNumber,
|
||||||
|
unit_of_measurement=UNIT_MILLI_VOLT,
|
||||||
|
device_class=DEVICE_CLASS_VOLTAGE,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_DIGITAL): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_SAMPLE_RATE): number.number_schema(
|
||||||
|
DigitalSampleRateNumber,
|
||||||
|
unit_of_measurement=UNIT_HERTZ,
|
||||||
|
device_class=DEVICE_CLASS_FREQUENCY,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_PILOT): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_FREQUENCY): number.number_schema(
|
||||||
|
PilotFrequencyNumber,
|
||||||
|
unit_of_measurement=UNIT_KILO_HERTZ,
|
||||||
|
device_class=DEVICE_CLASS_FREQUENCY,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_DEVIATION): number.number_schema(
|
||||||
|
PilotDeviationNumber,
|
||||||
|
unit_of_measurement=UNIT_KILO_HERTZ,
|
||||||
|
device_class=DEVICE_CLASS_FREQUENCY,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_REFCLK): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_FREQUENCY): number.number_schema(
|
||||||
|
RefClkFrequencyNumber,
|
||||||
|
unit_of_measurement=UNIT_HERTZ,
|
||||||
|
device_class=DEVICE_CLASS_FREQUENCY,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_PRESCALER): number.number_schema(
|
||||||
|
RefClkPrescalerNumber,
|
||||||
|
unit_of_measurement=UNIT_EMPTY,
|
||||||
|
device_class=DEVICE_CLASS_EMPTY,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_COMPRESSOR): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_THRESHOLD): number.number_schema(
|
||||||
|
AcompThresholdNumber,
|
||||||
|
unit_of_measurement=UNIT_DECIBEL,
|
||||||
|
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_GAIN): number.number_schema(
|
||||||
|
AcompGainNumber,
|
||||||
|
unit_of_measurement=UNIT_DECIBEL,
|
||||||
|
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_LIMITER): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_RELEASE_TIME): number.number_schema(
|
||||||
|
LimiterReleaseTimeNumber,
|
||||||
|
unit_of_measurement=UNIT_MILLISECOND,
|
||||||
|
device_class=DEVICE_CLASS_DURATION,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_ASQ): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_LEVEL_LOW): number.number_schema(
|
||||||
|
AsqLevelLowNumber,
|
||||||
|
unit_of_measurement=UNIT_DECIBEL,
|
||||||
|
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_DURATION_LOW): number.number_schema(
|
||||||
|
AsqDurationLowNumber,
|
||||||
|
unit_of_measurement=UNIT_MILLISECOND,
|
||||||
|
device_class=DEVICE_CLASS_DURATION,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_LEVEL_HIGH): number.number_schema(
|
||||||
|
AsqLevelHighNumber,
|
||||||
|
unit_of_measurement=UNIT_DECIBEL,
|
||||||
|
device_class=DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_DURATION_HIGH): number.number_schema(
|
||||||
|
AsqDurationHighNumber,
|
||||||
|
unit_of_measurement=UNIT_MILLISECOND,
|
||||||
|
device_class=DEVICE_CLASS_DURATION,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_RDS): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_DEVIATION): number.number_schema(
|
||||||
|
RdsDeviationNumber,
|
||||||
|
unit_of_measurement=UNIT_KILO_HERTZ,
|
||||||
|
device_class=DEVICE_CLASS_FREQUENCY,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def new_number(config, id, setter, min_value, max_value, step, *args):
|
async def new_number(parent, config, id, setter, min_value, max_value, step, *args, **kwargs):
|
||||||
if c := config.get(id):
|
if c := config.get(id):
|
||||||
|
if CONF_MODE in kwargs:
|
||||||
|
if CONF_MODE not in c or c[CONF_MODE] == number.NumberMode.NUMBER_MODE_AUTO:
|
||||||
|
c[CONF_MODE] = kwargs.get(CONF_MODE)
|
||||||
n = await number.new_number(
|
n = await number.new_number(
|
||||||
c, *args, min_value=min_value, max_value=max_value, step=step
|
c, *args, min_value=min_value, max_value=max_value, step=step
|
||||||
)
|
)
|
||||||
await cg.register_parented(n, config[CONF_SI4713_ID])
|
await cg.register_parented(n, parent)
|
||||||
cg.add(setter(n))
|
cg.add(setter(n))
|
||||||
|
return n
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
c = await cg.get_variable(config[CONF_SI4713_ID])
|
parent = await cg.get_variable(config[CONF_SI4713_ID])
|
||||||
await new_number(config, CONF_FREQUENCY, c.set_frequency_number, 76, 108, 0.05)
|
if tuner_config := config.get(CONF_SECTION_TUNER):
|
||||||
|
await new_number(parent, tuner_config, CONF_FREQUENCY, parent.set_frequency_number, 76, 108, 0.05)
|
||||||
|
await new_number(parent, tuner_config, CONF_DEVIATION, parent.set_audio_deviation_number, 0, 90, 0.01)
|
||||||
|
await new_number(parent, tuner_config, CONF_POWER, parent.set_power_number, 88, 115, 1, mode = number.NumberMode.NUMBER_MODE_SLIDER)
|
||||||
|
await new_number(parent, tuner_config, CONF_ANTCAP, parent.set_antcap_number, 0, 191, 1, mode = number.NumberMode.NUMBER_MODE_SLIDER)
|
||||||
|
if analog_config := config.get(CONF_SECTION_ANALOG):
|
||||||
|
await new_number(parent, analog_config, CONF_LEVEL, parent.set_analog_level_number, 0, 1023, 1, mode = number.NumberMode.NUMBER_MODE_SLIDER)
|
||||||
|
if digital_config := config.get(CONF_SECTION_DIGITAL):
|
||||||
|
await new_number(parent, digital_config, CONF_SAMPLE_RATE, parent.set_digital_sample_rate_number, 32000, 48000, 1)
|
||||||
|
if pilot_config := config.get(CONF_SECTION_PILOT):
|
||||||
|
await new_number(parent, pilot_config, CONF_FREQUENCY, parent.set_pilot_frequency_number, 0, 19, 0.001)
|
||||||
|
await new_number(parent, pilot_config, CONF_DEVIATION, parent.set_pilot_deviation_number, 0, 90, 0.001)
|
||||||
|
if refclk_config := config.get(CONF_SECTION_REFCLK):
|
||||||
|
await new_number(parent, refclk_config, CONF_FREQUENCY, parent.set_refclk_frequency_number, 31130, 34406, 1)
|
||||||
|
await new_number(parent, refclk_config, CONF_PRESCALER, parent.set_refclk_prescaler_number, 0, 4095, 1)
|
||||||
|
if compressor_config := config.get(CONF_SECTION_COMPRESSOR):
|
||||||
|
await new_number(parent, compressor_config, CONF_THRESHOLD, parent.set_acomp_threshold_number, -40, 0, 1)
|
||||||
|
await new_number(parent, compressor_config, CONF_GAIN, parent.set_acomp_gain_number, 0, 20, 1)
|
||||||
|
if limiter_config := config.get(CONF_SECTION_LIMITER):
|
||||||
|
await new_number(parent, limiter_config, CONF_RELEASE_TIME, parent.set_limiter_release_time_number, 0.25, 102.4, 0.01, mode = number.NumberMode.NUMBER_MODE_SLIDER)
|
||||||
|
if asq_config := config.get(CONF_SECTION_ASQ):
|
||||||
|
await new_number(parent, asq_config, CONF_LEVEL_LOW, parent.set_asq_level_low_number, -70, 0, 1)
|
||||||
|
await new_number(parent, asq_config, CONF_DURATION_LOW, parent.set_asq_duration_low_number, 0, 65535, 1)
|
||||||
|
await new_number(parent, asq_config, CONF_LEVEL_HIGH, parent.set_asq_level_high_number, -70, 0, 1)
|
||||||
|
await new_number(parent, asq_config, CONF_DURATION_HIGH, parent.set_asq_duration_high_number, 0, 65535, 1)
|
||||||
|
if rds_config := config.get(CONF_SECTION_RDS):
|
||||||
|
await new_number(parent, rds_config, CONF_DEVIATION, parent.set_rds_deviation_number, 0, 7.5, 0.01)
|
||||||
|
|
12
esphome/components/si4713_i2c/number/acomp_gain_number.cpp
Normal file
12
esphome/components/si4713_i2c/number/acomp_gain_number.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "acomp_gain_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void AcompGainNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_acomp_gain(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/number/acomp_gain_number.h
Normal file
18
esphome/components/si4713_i2c/number/acomp_gain_number.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class AcompGainNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
AcompGainNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "acomp_threshold_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void AcompThresholdNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_acomp_threshold(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class AcompThresholdNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
AcompThresholdNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
12
esphome/components/si4713_i2c/number/analog_level_number.cpp
Normal file
12
esphome/components/si4713_i2c/number/analog_level_number.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "analog_level_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void AnalogLevelNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_analog_level(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/number/analog_level_number.h
Normal file
18
esphome/components/si4713_i2c/number/analog_level_number.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class AnalogLevelNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
AnalogLevelNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
12
esphome/components/si4713_i2c/number/antcap_number.cpp
Normal file
12
esphome/components/si4713_i2c/number/antcap_number.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "antcap_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void AntcapNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_antcap(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/number/antcap_number.h
Normal file
18
esphome/components/si4713_i2c/number/antcap_number.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class AntcapNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
AntcapNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "audio_deviation_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void AudioDeviationNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_audio_deviation(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class AudioDeviationNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
AudioDeviationNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "digital_sample_rate_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void DigitalSampleRateNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_digital_sample_rate(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class DigitalSampleRateNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
DigitalSampleRateNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "limiter_release_time_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void LimiterReleaseTimeNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_limiter_release_time(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class LimiterReleaseTimeNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
LimiterReleaseTimeNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "pilot_deviation_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void PilotDeviationNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_pilot_deviation(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class PilotDeviationNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
PilotDeviationNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "pilot_frequency_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void PilotFrequencyNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_pilot_frequency(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class PilotFrequencyNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
PilotFrequencyNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
12
esphome/components/si4713_i2c/number/power_number.cpp
Normal file
12
esphome/components/si4713_i2c/number/power_number.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "power_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void PowerNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_power(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/number/power_number.h
Normal file
18
esphome/components/si4713_i2c/number/power_number.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class PowerNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
PowerNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "rds_deviation_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void RdsDeviationNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_rds_deviation(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/number/rds_deviation_number.h
Normal file
18
esphome/components/si4713_i2c/number/rds_deviation_number.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class RdsDeviationNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
RdsDeviationNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "refclk_frequency_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void RefClkFrequencyNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_refclk_frequency(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class RefClkFrequencyNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
RefClkFrequencyNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "refclk_prescaler_number.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void RefClkPrescalerNumber::control(float value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_refclk_prescaler(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/number/number.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class RefClkPrescalerNumber : public number::Number, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
RefClkPrescalerNumber() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(float value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -12,7 +12,7 @@ void BinaryOutput::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, " Pin: %d", this->pin_);
|
ESP_LOGCONFIG(TAG, " Pin: %d", this->pin_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Si4713BinaryOutput::write_state(bool state) {
|
void BinaryOutput::write_state(bool state) {
|
||||||
this->parent_->set_gpio(this->pin_, state);
|
this->parent_->set_gpio(this->pin_, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,34 +9,140 @@ from .. import (
|
||||||
CONF_SI4713_ID,
|
CONF_SI4713_ID,
|
||||||
Si4713Component,
|
Si4713Component,
|
||||||
si4713_ns,
|
si4713_ns,
|
||||||
CONF_,
|
CONF_SECTION_ANALOG,
|
||||||
ICON_SLEEP,
|
CONF_SECTION_DIGITAL,
|
||||||
|
CONF_SECTION_REFCLK,
|
||||||
|
CONF_SECTION_COMPRESSOR,
|
||||||
|
CONF_PRE_EMPHASIS,
|
||||||
|
CONF_ATTENUATION,
|
||||||
|
CONF_SAMPLE_BITS,
|
||||||
|
CONF_CHANNELS,
|
||||||
|
CONF_MODE,
|
||||||
|
CONF_CLOCK_EDGE,
|
||||||
|
CONF_SOURCE,
|
||||||
|
CONF_ATTACK,
|
||||||
|
CONF_RELEASE,
|
||||||
|
CONF_PRESET,
|
||||||
ICON_SINE_WAVE,
|
ICON_SINE_WAVE,
|
||||||
ICON_RESISTOR,
|
ICON_RESISTOR,
|
||||||
# T1M_SEL,
|
ICON_EAR_HEARING,
|
||||||
|
PRE_EMPHASIS,
|
||||||
|
LINE_ATTENUATION,
|
||||||
|
SAMPLE_BITS,
|
||||||
|
SAMPLE_CHANNELS,
|
||||||
|
DIGITAL_MODE,
|
||||||
|
DIGITAL_CLOCK_EDGE,
|
||||||
|
REFCLK_SOURCE,
|
||||||
|
ACOMP_ATTACK,
|
||||||
|
ACOMP_RELEASE,
|
||||||
|
ACOMP_PRESET,
|
||||||
)
|
)
|
||||||
|
|
||||||
#T1mSelSelect = si4713_ns.class_("T1mSelSelect", select.Select)
|
PreEmphasisSelect = si4713_ns.class_("PreEmphasisSelect", select.Select)
|
||||||
|
AnalogAttenuationSelect = si4713_ns.class_("AnalogAttenuationSelect", select.Select)
|
||||||
|
DigitalSampleBitsSelect = si4713_ns.class_("DigitalSampleBitsSelect", select.Select)
|
||||||
|
DigitalChannelsSelect = si4713_ns.class_("DigitalChannelsSelect", select.Select)
|
||||||
|
DigitalModeSelect = si4713_ns.class_("DigitalModeSelect", select.Select)
|
||||||
|
DigitalClockEdgeSelect = si4713_ns.class_("DigitalClockEdgeSelect", select.Select)
|
||||||
|
RefClkSourceSelect = si4713_ns.class_("RefClkSourceSelect", select.Select)
|
||||||
|
AcompAttackSelect = si4713_ns.class_("AcompAttackSelect", select.Select)
|
||||||
|
AcompReleaseSelect = si4713_ns.class_("AcompReleaseSelect", select.Select)
|
||||||
|
AcompPresetSelect = si4713_ns.class_("AcompPresetSelect", select.Select)
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.Schema(
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
|
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
|
||||||
# cv.Optional(CONF_T1M_SEL): select.select_schema(
|
cv.Optional(CONF_PRE_EMPHASIS): select.select_schema(
|
||||||
# T1mSelSelect,
|
PreEmphasisSelect,
|
||||||
# entity_category=ENTITY_CATEGORY_CONFIG,
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
# icon=ICON_SLEEP,
|
icon=ICON_SINE_WAVE,
|
||||||
# ),
|
),
|
||||||
|
cv.Optional(CONF_SECTION_ANALOG): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ATTENUATION): select.select_schema(
|
||||||
|
AnalogAttenuationSelect,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
icon=ICON_RESISTOR,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_DIGITAL): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_SAMPLE_BITS): select.select_schema(
|
||||||
|
DigitalSampleBitsSelect,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
# icon=ICON_,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_CHANNELS): select.select_schema(
|
||||||
|
DigitalChannelsSelect,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
icon=ICON_EAR_HEARING,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_MODE): select.select_schema(
|
||||||
|
DigitalModeSelect,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
# icon=ICON_,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_CLOCK_EDGE): select.select_schema(
|
||||||
|
DigitalClockEdgeSelect,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
icon=ICON_PULSE,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_REFCLK): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_SOURCE): select.select_schema(
|
||||||
|
RefClkSourceSelect,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
icon=ICON_PULSE,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_COMPRESSOR): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ATTACK): select.select_schema(
|
||||||
|
AcompAttackSelect,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
icon=ICON_SINE_WAVE,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_RELEASE): select.select_schema(
|
||||||
|
AcompReleaseSelect,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
icon=ICON_SINE_WAVE,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_PRESET): select.select_schema(
|
||||||
|
AcompPresetSelect,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
icon=ICON_SINE_WAVE,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def new_select(config, id, setter, options):
|
async def new_select(parent, config, id, setter, options):
|
||||||
if c := config.get(id):
|
if c := config.get(id):
|
||||||
s = await select.new_select(c, options=list(options.keys()))
|
s = await select.new_select(c, options=list(options.keys()))
|
||||||
await cg.register_parented(s, config[CONF_SI4713_ID])
|
await cg.register_parented(s, parent)
|
||||||
cg.add(setter(s))
|
cg.add(setter(s))
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
c = await cg.get_variable(config[CONF_SI4713_ID])
|
parent = await cg.get_variable(config[CONF_SI4713_ID])
|
||||||
# await new_select(config, CONF_T1M_SEL, c.set_t1m_sel_select, T1M_SEL)
|
await new_select(parent, config, CONF_PRE_EMPHASIS, parent.set_pre_emphasis_select, PRE_EMPHASIS)
|
||||||
|
if analog_config := config.get(CONF_SECTION_ANALOG):
|
||||||
|
await new_select(parent, analog_config, CONF_ATTENUATION, parent.set_analog_attenuation_select, LINE_ATTENUATION)
|
||||||
|
if digital_config := config.get(CONF_SECTION_DIGITAL):
|
||||||
|
await new_select(parent, digital_config, CONF_SAMPLE_BITS, parent.set_digital_sample_bits_select, SAMPLE_BITS)
|
||||||
|
await new_select(parent, digital_config, CONF_CHANNELS, parent.set_digital_channels_select, SAMPLE_CHANNELS)
|
||||||
|
await new_select(parent, digital_config, CONF_MODE, parent.set_digital_mode_select, DIGITAL_MODE)
|
||||||
|
await new_select(parent, digital_config, CONF_CLOCK_EDGE, parent.set_digital_clock_edge_select, DIGITAL_CLOCK_EDGE)
|
||||||
|
if refclk_config := config.get(CONF_SECTION_REFCLK):
|
||||||
|
await new_select(parent, refclk_config, CONF_SOURCE, parent.set_refclk_source_select, REFCLK_SOURCE)
|
||||||
|
if compressor_config := config.get(CONF_SECTION_COMPRESSOR):
|
||||||
|
await new_select(parent, compressor_config, CONF_ATTACK, parent.set_acomp_attack_select, ACOMP_ATTACK)
|
||||||
|
await new_select(parent, compressor_config, CONF_RELEASE, parent.set_acomp_release_select, ACOMP_RELEASE)
|
||||||
|
await new_select(parent, compressor_config, CONF_PRESET, parent.set_acomp_preset_select, ACOMP_PRESET)
|
||||||
|
|
14
esphome/components/si4713_i2c/select/acomp_attack_select.cpp
Normal file
14
esphome/components/si4713_i2c/select/acomp_attack_select.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "acomp_attack_select.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void AcompAttackSelect::control(const std::string &value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
if (auto index = this->active_index()) {
|
||||||
|
this->parent_->set_acomp_attack((AcompAttack) *index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/select/acomp_attack_select.h
Normal file
18
esphome/components/si4713_i2c/select/acomp_attack_select.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class AcompAttackSelect : public select::Select, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
AcompAttackSelect() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
14
esphome/components/si4713_i2c/select/acomp_preset_select.cpp
Normal file
14
esphome/components/si4713_i2c/select/acomp_preset_select.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "acomp_preset_select.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void AcompPresetSelect::control(const std::string &value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
if (auto index = this->active_index()) {
|
||||||
|
this->parent_->set_acomp_preset((AcompPreset) *index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/select/acomp_preset_select.h
Normal file
18
esphome/components/si4713_i2c/select/acomp_preset_select.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class AcompPresetSelect : public select::Select, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
AcompPresetSelect() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "acomp_release_select.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void AcompReleaseSelect::control(const std::string &value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
if (auto index = this->active_index()) {
|
||||||
|
this->parent_->set_acomp_release((AcompRelease) *index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/select/acomp_release_select.h
Normal file
18
esphome/components/si4713_i2c/select/acomp_release_select.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class AcompReleaseSelect : public select::Select, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
AcompReleaseSelect() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "analog_attenuation_select.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void AnalogAttenuationSelect::control(const std::string &value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
if (auto index = this->active_index()) {
|
||||||
|
this->parent_->set_analog_attenuation((LineAttenuation) *index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class AnalogAttenuationSelect : public select::Select, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
AnalogAttenuationSelect() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "digital_channels_select.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void DigitalChannelsSelect::control(const std::string &value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
if (auto index = this->active_index()) {
|
||||||
|
this->parent_->set_digital_channels((SampleChannels) *index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class DigitalChannelsSelect : public select::Select, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
DigitalChannelsSelect() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "digital_clock_edge_select.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void DigitalClockEdgeSelect::control(const std::string &value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
if (auto index = this->active_index()) {
|
||||||
|
this->parent_->set_digital_clock_edge((DigitalClockEdge) *index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class DigitalClockEdgeSelect : public select::Select, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
DigitalClockEdgeSelect() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
14
esphome/components/si4713_i2c/select/digital_mode_select.cpp
Normal file
14
esphome/components/si4713_i2c/select/digital_mode_select.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "digital_mode_select.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void DigitalModeSelect::control(const std::string &value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
if (auto index = this->active_index()) {
|
||||||
|
this->parent_->set_digital_mode((DigitalMode) *index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/select/digital_mode_select.h
Normal file
18
esphome/components/si4713_i2c/select/digital_mode_select.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class DigitalModeSelect : public select::Select, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
DigitalModeSelect() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "digital_sample_bits_select.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void DigitalSampleBitsSelect::control(const std::string &value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
if (auto index = this->active_index()) {
|
||||||
|
this->parent_->set_digital_sample_bits((SampleBits) *index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class DigitalSampleBitsSelect : public select::Select, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
DigitalSampleBitsSelect() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
14
esphome/components/si4713_i2c/select/pre_emphasis_select.cpp
Normal file
14
esphome/components/si4713_i2c/select/pre_emphasis_select.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "pre_emphasis_select.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void PreEmphasisSelect::control(const std::string &value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
if (auto index = this->active_index()) {
|
||||||
|
this->parent_->set_pre_emphasis((PreEmphasis) *index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/select/pre_emphasis_select.h
Normal file
18
esphome/components/si4713_i2c/select/pre_emphasis_select.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class PreEmphasisSelect : public select::Select, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
PreEmphasisSelect() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include "refclk_source_select.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void RefClkSourceSelect::control(const std::string &value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
if (auto index = this->active_index()) {
|
||||||
|
this->parent_->set_refclk_source((RefClkSource) *index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/select/refclk_source_select.h
Normal file
18
esphome/components/si4713_i2c/select/refclk_source_select.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/select/select.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class RefClkSourceSelect : public select::Select, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
RefClkSourceSelect() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -15,13 +15,12 @@ static const char *const TAG = "si4713";
|
||||||
Si4713Component::Si4713Component() {
|
Si4713Component::Si4713Component() {
|
||||||
this->reset_pin_ = nullptr;
|
this->reset_pin_ = nullptr;
|
||||||
this->reset_ = false;
|
this->reset_ = false;
|
||||||
|
this->op_mode_ = OpMode::OPMODE_ANALOG;
|
||||||
|
this->frequency_ = 8750;
|
||||||
|
this->power_ = 115;
|
||||||
|
this->antcap_ = 0;
|
||||||
|
this->tx_acomp_preset_ = AcompPreset::ACOMP_CUSTOM;
|
||||||
memset(this->gpio_, 0, sizeof(gpio_));
|
memset(this->gpio_, 0, sizeof(gpio_));
|
||||||
// memset(&this->state_, 0, sizeof(this->state_));
|
|
||||||
this->rds_station_pos_ = 0;
|
|
||||||
this->rds_text_pos_ = 0;
|
|
||||||
// this->state_. = ;
|
|
||||||
// our defaults
|
|
||||||
// this->state_. = ; // start with tx enabled
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Si4713Component::send_cmd(const void *cmd, size_t cmd_size, void *res, size_t res_size) {
|
bool Si4713Component::send_cmd(const void *cmd, size_t cmd_size, void *res, size_t res_size) {
|
||||||
|
@ -66,171 +65,6 @@ bool Si4713Component::send_cmd(const void *cmd, size_t cmd_size, void *res, size
|
||||||
|
|
||||||
void Si4713Component::rds_update_() {}
|
void Si4713Component::rds_update_() {}
|
||||||
|
|
||||||
// overrides
|
|
||||||
|
|
||||||
void Si4713Component::setup() {
|
|
||||||
// CHIP STATE: POWER DOWN
|
|
||||||
|
|
||||||
if (!this->power_up()) {
|
|
||||||
this->mark_failed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->detect_chip_id()) {
|
|
||||||
this->mark_failed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CHIP STATE: POWER UP
|
|
||||||
|
|
||||||
uint16_t pilot = 1;
|
|
||||||
uint16_t stereo = 1;
|
|
||||||
uint16_t rds = 0;
|
|
||||||
uint16_t fmpe = 1;
|
|
||||||
uint16_t acen = 0;
|
|
||||||
uint16_t limiter = 1;
|
|
||||||
uint16_t digital = 0;
|
|
||||||
|
|
||||||
// Use GPO?
|
|
||||||
|
|
||||||
// Set RCLK settings
|
|
||||||
this->set_prop(PropRefClkFreq(32768));
|
|
||||||
this->set_prop(PropRefClkPreScale(1, 0)); // div1, RCLK source
|
|
||||||
|
|
||||||
// Mono/Stereo?
|
|
||||||
this->set_prop(PropTxPilotFrequency(19000));
|
|
||||||
this->set_prop(PropTxPilotDeviation(675));
|
|
||||||
this->set_prop(PropTxComponentEnable(pilot, stereo, rds));
|
|
||||||
|
|
||||||
// Set Audio Deviation
|
|
||||||
this->set_prop(PropTxAudioDeviation(6825));
|
|
||||||
|
|
||||||
// Transmit RDS?
|
|
||||||
// this->set_prop(PropTxRdsDeviation(200));
|
|
||||||
// if(rds) PropTxRds*
|
|
||||||
// if(rds) CmdTxRdsPs
|
|
||||||
// if(rds) CmdTxRdsBuff
|
|
||||||
|
|
||||||
// Preemphasis?
|
|
||||||
this->set_prop(PropTxPreEmphasis(fmpe));
|
|
||||||
this->set_prop(PropTxAcompEnable(acen, limiter));
|
|
||||||
|
|
||||||
// Compressor?
|
|
||||||
if (acen) {
|
|
||||||
// minimal compression
|
|
||||||
this->set_prop(PropTxAcompThreshold(-40)); // -40dBFS
|
|
||||||
this->set_prop(PropTxAcompAttackTime(0)); // 5ms
|
|
||||||
this->set_prop(PropTxAcompReleaseTime(0)); // 100ms
|
|
||||||
this->set_prop(PropTxAcompGain(15)); // 15dB
|
|
||||||
// aggressive compression
|
|
||||||
// this->set_prop(PropTxAcompThreshold(-15)); // -15dBFS
|
|
||||||
// this->set_prop(PropTxAcompAttackTime(9)); // 0.5ms
|
|
||||||
// this->set_prop(PropTxAcompReleaseTime(4)); // 1000ms
|
|
||||||
// this->set_prop(PropTxAcompGain(5)); // 5dB
|
|
||||||
}
|
|
||||||
|
|
||||||
// Limiter?
|
|
||||||
if (limiter) {
|
|
||||||
this->set_prop(PropTxLimiterReleaseTime(102)); // 5.01 ms
|
|
||||||
}
|
|
||||||
|
|
||||||
this->tune_freq(8750);
|
|
||||||
this->tune_power(115);
|
|
||||||
|
|
||||||
// CHIP STATE: TRANSMITTING
|
|
||||||
|
|
||||||
if (digital) {
|
|
||||||
// Digital Audio Input?
|
|
||||||
this->set_prop(PropDigitalInputFormat(0, 0, 1, 0)); // 16-bit, stereo, I2S mode, rising edge
|
|
||||||
this->set_prop(PropDigitalInputSampleRate(44100));
|
|
||||||
} else {
|
|
||||||
// Analog Audio Input?
|
|
||||||
this->set_prop(PropTxLineInputLevel(636, 3)); // 636 mvPK, 60 kOhm
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mute?
|
|
||||||
this->set_prop(PropTxLineInputMute(0, 0)); // left no mute, right no mute
|
|
||||||
// Optional: Mute or Unmute Audio based on ASQ status
|
|
||||||
|
|
||||||
// Enable GPIO1, GPIO2
|
|
||||||
// TOOD:
|
|
||||||
// output:
|
|
||||||
// - platform: si4713
|
|
||||||
// pin: 1/2
|
|
||||||
// ...
|
|
||||||
this->send_cmd(CmdGpioCtl(1, 1));
|
|
||||||
/*
|
|
||||||
this->set_interval(3000, [this]() {
|
|
||||||
static uint8_t gpio1 = 0, gpio2 = 0;
|
|
||||||
this->send_cmd(CmdGpioSet(gpio1++ & 1, gpio2++ & 1));
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
this->set_interval(3000, [this]() {
|
|
||||||
ResTxTuneStatus res;
|
|
||||||
if (this->send_cmd(CmdTxTuneStatus(), res)) {
|
|
||||||
ESP_LOGD(TAG, "ResTxTuneStatus FREQ %d RFdBuV %d ANTCAP %d NL %d", (res.READFREQH << 8) | res.READFREQL,
|
|
||||||
res.READRFdBuV, res.READANTCAP, res.RNL);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Monitor Audio Signal Quality (ASQ)?
|
|
||||||
// TODO: PropTxAsqInterruptSource
|
|
||||||
// TODO: PropTxAsqLevelLow
|
|
||||||
// TODO: PropTxAsqDurationLow
|
|
||||||
// TODO: PropTxAsqLevelHigh
|
|
||||||
// TODO: PropTxAsqDurationHigh
|
|
||||||
|
|
||||||
this->set_interval(3000, [this]() {
|
|
||||||
ResTxAsqStatus res;
|
|
||||||
if (this->send_cmd(CmdTxAsqStatus(), res)) {
|
|
||||||
ESP_LOGD(TAG, "ResTxAsqStatus OVERMOD %d IALH %d IALL %d INLEVEL %d", res.OVERMOD, res.IALH, res.IALL,
|
|
||||||
res.INLEVEL);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
this->publish_frequency();
|
|
||||||
this->publish_mute();
|
|
||||||
this->publish_mono();
|
|
||||||
this->publish_rds_enable();
|
|
||||||
this->publish_rds_station();
|
|
||||||
this->publish_rds_text();
|
|
||||||
this->publish_gpio(0);
|
|
||||||
this->publish_gpio(1);
|
|
||||||
this->publish_gpio(2);
|
|
||||||
|
|
||||||
this->set_interval(1000, [this]() { this->rds_update_(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void Si4713Component::dump_config() {
|
|
||||||
ESP_LOGCONFIG(TAG, "Si4713:");
|
|
||||||
LOG_I2C_DEVICE(this);
|
|
||||||
if (this->is_failed()) {
|
|
||||||
ESP_LOGE(TAG, "failed!");
|
|
||||||
}
|
|
||||||
ESP_LOGCONFIG(TAG, " Chip: %s", this->chip_id_.c_str());
|
|
||||||
ESP_LOGCONFIG(TAG, " Frequency: %.2f MHz", this->get_frequency());
|
|
||||||
ESP_LOGCONFIG(TAG, " RDS station: %s", this->rds_station_.c_str());
|
|
||||||
ESP_LOGCONFIG(TAG, " RDS text: %s", this->rds_text_.c_str());
|
|
||||||
// TODO: ...and everything else...
|
|
||||||
LOG_UPDATE_INTERVAL(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Si4713Component::update() {
|
|
||||||
/*
|
|
||||||
if (this->read_reg_(REG_)) {
|
|
||||||
this->publish_();
|
|
||||||
} else {
|
|
||||||
ESP_LOGE(TAG, "update cannot read the status register");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void Si4713Component::loop() {}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
bool Si4713Component::reset() {
|
bool Si4713Component::reset() {
|
||||||
if (this->reset_pin_ == nullptr) {
|
if (this->reset_pin_ == nullptr) {
|
||||||
ESP_LOGE(TAG, "cannot reset device, reset pin is not set");
|
ESP_LOGE(TAG, "cannot reset device, reset pin is not set");
|
||||||
|
@ -253,15 +87,16 @@ bool Si4713Component::reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Si4713Component::power_up() {
|
bool Si4713Component::power_up() {
|
||||||
// Note: In FMTX component 1.0 and 2.0, a reset is required when the system
|
// NOTE: In FMTX component 1.0 and 2.0, a reset is required when the system
|
||||||
// controller writes a command other than POWER_UP when in powerdown mode
|
// controller writes a command other than POWER_UP when in powerdown mode
|
||||||
this->reset();
|
this->reset();
|
||||||
|
|
||||||
CmdPowerUp cmd;
|
CmdPowerUp cmd;
|
||||||
cmd.FUNC = 2;
|
cmd.OPMODE = (uint8_t) this->op_mode_;
|
||||||
cmd.XOSCEN = 1; // TODO: external oscillator
|
cmd.FUNC = 2; // transmit
|
||||||
cmd.OPMODE = 0x50; // TODO: digital
|
cmd.XOSCEN = this->op_mode_ == OpMode::OPMODE_ANALOG ? 1 : 0; // auto-enable(?) xtal for analog mode
|
||||||
cmd.GPO2OEN = 0; // TODO: GPIO2 enable
|
cmd.GPO2OEN = 0; // we do this later
|
||||||
|
cmd.CTSIEN = 0; // no interrupts
|
||||||
return this->send_cmd(cmd);
|
return this->send_cmd(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +112,7 @@ bool Si4713Component::detect_chip_id() {
|
||||||
snprintf(buff, sizeof(buff), "Si47%02d Rev %d", res.PN, res.CHIPREV);
|
snprintf(buff, sizeof(buff), "Si47%02d Rev %d", res.PN, res.CHIPREV);
|
||||||
this->chip_id_ = buff;
|
this->chip_id_ = buff;
|
||||||
|
|
||||||
// TODO: support all transmitters 10/11/12/13/20/21
|
// TODO: support all transmitters 10/11/12/13/20/21, mask unsupported features
|
||||||
|
|
||||||
if (res.PN != 10 && res.PN != 11 && res.PN != 12 && res.PN != 13) {
|
if (res.PN != 10 && res.PN != 11 && res.PN != 12 && res.PN != 13) {
|
||||||
ESP_LOGE(TAG, "Si47%02d is not supported", res.PN);
|
ESP_LOGE(TAG, "Si47%02d is not supported", res.PN);
|
||||||
|
@ -317,124 +152,694 @@ bool Si4713Component::tune_wait() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// config
|
// overrides
|
||||||
|
|
||||||
void Si4713Component::set_reset_pin(InternalGPIOPin *pin) { this->reset_pin_ = pin; }
|
void Si4713Component::setup() {
|
||||||
|
// CHIP STATE: POWER DOWN
|
||||||
|
|
||||||
void Si4713Component::set_frequency(float value) {
|
if (!this->power_up()) {
|
||||||
if (!(CH_FREQ_MIN <= value && value <= CH_FREQ_MAX)) {
|
this->mark_failed();
|
||||||
ESP_LOGE(TAG, "set_frequency(%.2f) invalid (%.2f - %.2f)", value, CH_FREQ_MIN, CH_FREQ_MAX);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int f = clamp((int) std::lround((value - 76) * 20), CH_FREQ_RAW_MIN, CH_FREQ_RAW_MAX);
|
if (!this->detect_chip_id()) {
|
||||||
// this->state_.CH_UPPER = (uint8_t) (f >> 8);
|
this->mark_failed();
|
||||||
// this->state_.CH_LOWER = (uint8_t) (f & 0xff);
|
return;
|
||||||
// this->write_reg_(REG_SYSTEM_ADDR);
|
}
|
||||||
// this->write_reg_(REG_CH1_ADDR);
|
|
||||||
|
|
||||||
|
// CHIP STATE: POWER UP
|
||||||
|
|
||||||
|
// Set RCLK settings
|
||||||
|
this->set_prop(this->refclk_freq_);
|
||||||
|
this->set_prop(this->refclk_prescale_);
|
||||||
|
// Mono/Stereo?
|
||||||
|
this->set_prop(this->tx_pilot_frequency_);
|
||||||
|
this->set_prop(this->tx_pilot_deviation_);
|
||||||
|
this->set_prop(this->tx_component_enable_);
|
||||||
|
// Set Audio Deviation
|
||||||
|
this->set_prop(this->tx_audio_deviation_);
|
||||||
|
// Transmit RDS?
|
||||||
|
this->set_prop(this->tx_rds_deviation_);
|
||||||
|
// Preemphasis?
|
||||||
|
this->set_prop(this->tx_pre_emphasis_);
|
||||||
|
this->set_prop(this->tx_acomp_enable_);
|
||||||
|
// Compressor?
|
||||||
|
// if (tx_acomp_enable_.ACEN) {
|
||||||
|
this->set_prop(this->tx_acomp_threshold_);
|
||||||
|
this->set_prop(this->tx_acomp_attack_time_);
|
||||||
|
this->set_prop(this->tx_acomp_release_time_);
|
||||||
|
this->set_prop(this->tx_acomp_gain_);
|
||||||
|
//}
|
||||||
|
// Limiter?
|
||||||
|
// if (tx_acomp_enable_.LIMITEN) {
|
||||||
|
this->set_prop(tx_limiter_releasee_time_);
|
||||||
|
//}
|
||||||
|
// Tune
|
||||||
|
this->tune_freq(this->frequency_);
|
||||||
|
this->tune_power(this->power_, this->antcap_);
|
||||||
|
|
||||||
|
// CHIP STATE: TRANSMITTING
|
||||||
|
|
||||||
|
// if (this->op_mode_ == OpMode::OPMODE_DIGITAL) {
|
||||||
|
// Digital Audio Input?
|
||||||
|
this->set_prop(digital_input_format_);
|
||||||
|
this->set_prop(digital_input_sample_rate_);
|
||||||
|
//} else if (this->op_mode_ == OpMode::OPMODE_ANALOG) {
|
||||||
|
// Analog Audio Input?
|
||||||
|
this->set_prop(tx_line_input_level_);
|
||||||
|
//}
|
||||||
|
// Mute? Optional: Mute or Unmute Audio based on ASQ status
|
||||||
|
this->set_prop(this->tx_line_input_mute_);
|
||||||
|
// GPIO
|
||||||
|
this->send_cmd(CmdGpioCtl(1, 1, 0)); // enable gpio1 and gpio2, clock is on gpio3
|
||||||
|
this->send_cmd(CmdGpioSet(0, 0, 0)); // init gpio to low (TODO: config)
|
||||||
|
// AQS
|
||||||
|
this->set_prop(this->tx_asq_interrupt_source_);
|
||||||
|
this->set_prop(this->tx_asq_level_low_);
|
||||||
|
this->set_prop(this->tx_asq_duration_low_);
|
||||||
|
this->set_prop(this->tx_asq_level_high_);
|
||||||
|
this->set_prop(this->tx_asq_duration_high_);
|
||||||
|
// RDS
|
||||||
|
// TODO: PropTxRds*, CmdTxRdsPs, CmdTxRdsBuff
|
||||||
|
|
||||||
|
// publish
|
||||||
|
|
||||||
|
this->publish_mute();
|
||||||
|
this->publish_mono();
|
||||||
|
this->publish_pre_emphasis();
|
||||||
this->publish_frequency();
|
this->publish_frequency();
|
||||||
|
this->publish_audio_deviation();
|
||||||
|
this->publish_power();
|
||||||
|
this->publish_antcap();
|
||||||
|
this->publish_analog_level();
|
||||||
|
this->publish_analog_attenuation();
|
||||||
|
this->publish_digital_sample_rate();
|
||||||
|
this->publish_digital_sample_bits();
|
||||||
|
this->publish_digital_channels();
|
||||||
|
this->publish_digital_mode();
|
||||||
|
this->publish_digital_clock_edge();
|
||||||
|
this->publish_pilot_enable();
|
||||||
|
this->publish_pilot_frequency();
|
||||||
|
this->publish_pilot_deviation();
|
||||||
|
this->publish_refclk_frequency();
|
||||||
|
this->publish_refclk_source();
|
||||||
|
this->publish_refclk_prescaler();
|
||||||
|
this->publish_acomp_enable();
|
||||||
|
this->publish_acomp_threshold();
|
||||||
|
this->publish_acomp_attack();
|
||||||
|
this->publish_acomp_release();
|
||||||
|
this->publish_acomp_gain();
|
||||||
|
this->publish_acomp_preset();
|
||||||
|
this->publish_limiter_enable();
|
||||||
|
this->publish_limiter_release_time();
|
||||||
|
this->publish_asq_overmod_enable();
|
||||||
|
this->publish_asq_ialh_enable();
|
||||||
|
this->publish_asq_iall_enable();
|
||||||
|
this->publish_asq_level_low();
|
||||||
|
this->publish_asq_duration_low();
|
||||||
|
this->publish_asq_level_high();
|
||||||
|
this->publish_asq_duration_high();
|
||||||
|
this->publish_rds_enable();
|
||||||
|
this->publish_rds_deviation();
|
||||||
|
this->publish_rds_station();
|
||||||
|
this->publish_rds_text();
|
||||||
|
this->publish_gpio(0);
|
||||||
|
this->publish_gpio(1);
|
||||||
|
this->publish_gpio(2);
|
||||||
|
this->publish_chip_id();
|
||||||
|
|
||||||
|
this->set_interval(1000, [this]() { this->rds_update_(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
float Si4713Component::get_frequency() {
|
void Si4713Component::dump_config() {
|
||||||
// uint16_t ch = ((uint16_t) this->state_.CH_UPPER << 8) | this->state_.CH_LOWER;
|
ESP_LOGCONFIG(TAG, "Si4713:");
|
||||||
// return (float) ch / 20 + 76;
|
LOG_I2C_DEVICE(this);
|
||||||
return 0;
|
if (this->is_failed()) {
|
||||||
|
ESP_LOGE(TAG, "failed!");
|
||||||
|
}
|
||||||
|
ESP_LOGCONFIG(TAG, " Chip: %s", this->chip_id_.c_str());
|
||||||
|
ESP_LOGCONFIG(TAG, " Frequency: %.2f MHz", this->get_frequency());
|
||||||
|
ESP_LOGCONFIG(TAG, " RDS station: %s", this->rds_station_.c_str());
|
||||||
|
ESP_LOGCONFIG(TAG, " RDS text: %s", this->rds_text_.c_str());
|
||||||
|
// TODO: ...and everything else...
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Si4713Component::update() {
|
||||||
|
// TODO: publish to sensors
|
||||||
|
ResTxTuneStatus res;
|
||||||
|
if (this->send_cmd(CmdTxTuneStatus(), res)) {
|
||||||
|
ESP_LOGD(TAG, "ResTxTuneStatus FREQ %d RFdBuV %d ANTCAP %d NL %d", (res.READFREQH << 8) | res.READFREQL,
|
||||||
|
res.READRFdBuV, res.READANTCAP, res.RNL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::loop() {
|
||||||
|
ResGetIntStatus res1;
|
||||||
|
if (this->send_cmd(CmdGetIntStatus(), res1) && res1.ASQINT == 1) {
|
||||||
|
ResTxAsqStatus res2;
|
||||||
|
if (this->send_cmd(CmdTxAsqStatus(), res2)) {
|
||||||
|
ESP_LOGD(TAG, "ResTxAsqStatus %08X OVERMOD %d IALH %d IALL %d INLEVEL %d", res2.RESP[0], res2.OVERMOD, res2.IALH,
|
||||||
|
res2.IALL, res2.INLEVEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// config
|
||||||
|
|
||||||
|
#define CHECK_ENUM(value) \
|
||||||
|
if (value >= GET_ENUM_LAST(value)) { \
|
||||||
|
ESP_LOGE(TAG, "%s(%d) invalid", __func__, (int) value); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_FLOAT_RANGE(value, min_value, max_value) \
|
||||||
|
if (!(min_value <= value && value <= max_value)) { \
|
||||||
|
ESP_LOGE(TAG, "%s(%.2f) invalid (%.2f - %.2f)", __func__, value, min_value, max_value); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_INT_RANGE(value, min_value, max_value) \
|
||||||
|
if (!(min_value <= value && value <= max_value)) { \
|
||||||
|
ESP_LOGE(TAG, "%s(%d) invalid (%d - %d)", __func__, value, min_value, max_value); \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_TEXT_RANGE(value, max_size) \
|
||||||
|
if (value.size() > max_size) { \
|
||||||
|
ESP_LOGW(TAG, "%s(%s) invalid (max %d characters)", __func__, value.c_str(), max_size); \
|
||||||
|
value.resize(max_size); \
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::set_reset_pin(InternalGPIOPin *pin) { this->reset_pin_ = pin; }
|
||||||
|
|
||||||
|
void Si4713Component::set_op_mode(OpMode value) { this->op_mode_ = (OpMode) value; }
|
||||||
|
|
||||||
void Si4713Component::set_mute(bool value) {
|
void Si4713Component::set_mute(bool value) {
|
||||||
// this->state_.MUTE = value ? 1 : 0;
|
this->tx_line_input_mute_.LIMUTE = value ? 1 : 0;
|
||||||
// this->write_reg_(REG_SYSTEM_ADDR);
|
this->tx_line_input_mute_.RIMUTE = value ? 1 : 0;
|
||||||
|
this->set_prop(this->tx_line_input_mute_);
|
||||||
this->publish_mute();
|
this->publish_mute();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Si4713Component::get_mute() {
|
bool Si4713Component::get_mute() {
|
||||||
// return this->state_.MUTE == 1;
|
return this->tx_line_input_mute_.LIMUTE != 0 && this->tx_line_input_mute_.RIMUTE != 0;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Si4713Component::set_mono(bool value) {
|
void Si4713Component::set_mono(bool value) {
|
||||||
// this->state_.MONO = value ? 1 : 0;
|
// NOTE: analog/digital mono linked, easier to control this way
|
||||||
// this->write_reg_(REG_SYSTEM_ADDR);
|
this->tx_component_enable_.LMR = value ? 0 : 1;
|
||||||
|
this->set_prop(this->tx_component_enable_);
|
||||||
this->publish_mono();
|
this->publish_mono();
|
||||||
|
this->digital_input_format_.IMONO = value ? 1 : 0;
|
||||||
|
this->set_prop(this->digital_input_format_);
|
||||||
|
this->publish_digital_channels();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Si4713Component::get_mono() {
|
bool Si4713Component::get_mono() { return this->tx_component_enable_.LMR == 0; }
|
||||||
// return this->state_.MONO == 1;
|
|
||||||
return false;
|
void Si4713Component::set_pre_emphasis(PreEmphasis value) {
|
||||||
|
CHECK_ENUM(value)
|
||||||
|
this->tx_pre_emphasis_.FMPE = (uint16_t) value;
|
||||||
|
this->set_prop(this->tx_pre_emphasis_);
|
||||||
|
this->publish_pre_emphasis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PreEmphasis Si4713Component::get_pre_emphasis() { return (PreEmphasis) tx_pre_emphasis_.FMPE; }
|
||||||
|
|
||||||
|
void Si4713Component::set_frequency(float value) {
|
||||||
|
CHECK_FLOAT_RANGE(value, FREQ_MIN, FREQ_MAX)
|
||||||
|
this->frequency_ = (uint16_t) clamp((int) std::lround(value * 100), FREQ_RAW_MIN, FREQ_RAW_MAX);
|
||||||
|
this->tune_freq(this->frequency_);
|
||||||
|
this->publish_frequency();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Si4713Component::get_frequency() { return (float) this->frequency_ / 100; }
|
||||||
|
|
||||||
|
void Si4713Component::set_audio_deviation(float value) {
|
||||||
|
CHECK_FLOAT_RANGE(value, TXADEV_MIN, TXADEV_MAX)
|
||||||
|
this->tx_audio_deviation_.TXADEV = (uint16_t) clamp((int) std::lround(value * 100), TXADEV_RAW_MIN, TXADEV_RAW_MAX);
|
||||||
|
this->set_prop(this->tx_audio_deviation_);
|
||||||
|
this->publish_audio_deviation();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Si4713Component::get_audio_deviation() { return (float) this->tx_audio_deviation_.TXADEV / 100; }
|
||||||
|
|
||||||
|
void Si4713Component::set_power(int value) {
|
||||||
|
CHECK_INT_RANGE(value, POWER_MIN, POWER_MAX)
|
||||||
|
this->power_ = (uint8_t) value;
|
||||||
|
this->tune_power(this->power_, this->antcap_);
|
||||||
|
this->publish_power();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_power() { return (int) this->power_; }
|
||||||
|
|
||||||
|
void Si4713Component::set_antcap(int value) {
|
||||||
|
CHECK_INT_RANGE(value, ANTCAP_MIN, ANTCAP_MAX)
|
||||||
|
this->antcap_ = (uint8_t) value;
|
||||||
|
this->tune_power(this->power_, this->antcap_);
|
||||||
|
this->publish_antcap();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_antcap() { return (int) this->antcap_; }
|
||||||
|
|
||||||
|
void Si4713Component::set_analog_level(int value) {
|
||||||
|
CHECK_INT_RANGE(value, LILEVEL_MIN, LILEVEL_MAX)
|
||||||
|
this->tx_line_input_level_.LILEVEL = (uint16_t) value;
|
||||||
|
this->set_prop(this->tx_line_input_level_);
|
||||||
|
this->publish_analog_level();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_analog_level() { return (int) this->tx_line_input_level_.LILEVEL; }
|
||||||
|
|
||||||
|
void Si4713Component::set_analog_attenuation(LineAttenuation value) {
|
||||||
|
CHECK_ENUM(value)
|
||||||
|
this->tx_line_input_level_.LIATTEN = (uint16_t) value;
|
||||||
|
this->set_prop(this->tx_line_input_level_);
|
||||||
|
this->publish_analog_attenuation();
|
||||||
|
}
|
||||||
|
|
||||||
|
LineAttenuation Si4713Component::get_analog_attenuation() {
|
||||||
|
return (LineAttenuation) this->tx_line_input_level_.LIATTEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::set_digital_sample_rate(int value) {
|
||||||
|
CHECK_INT_RANGE(value, DISR_MIN, DISR_MAX)
|
||||||
|
this->digital_input_sample_rate_.DISR = (uint16_t) value;
|
||||||
|
this->set_prop(this->digital_input_sample_rate_);
|
||||||
|
this->publish_digital_sample_rate();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_digital_sample_rate() { return (int) this->digital_input_sample_rate_.DISR; }
|
||||||
|
|
||||||
|
void Si4713Component::set_digital_sample_bits(SampleBits value) {
|
||||||
|
CHECK_ENUM(value)
|
||||||
|
this->digital_input_format_.ISIZE = (uint16_t) value;
|
||||||
|
this->set_prop(this->digital_input_format_);
|
||||||
|
this->publish_digital_sample_bits();
|
||||||
|
}
|
||||||
|
|
||||||
|
SampleBits Si4713Component::get_digital_sample_bits() { return (SampleBits) this->digital_input_format_.ISIZE; }
|
||||||
|
|
||||||
|
void Si4713Component::set_digital_channels(SampleChannels value) {
|
||||||
|
CHECK_ENUM(value)
|
||||||
|
this->digital_input_format_.IMONO = (uint16_t) value;
|
||||||
|
this->set_prop(this->digital_input_format_);
|
||||||
|
this->publish_digital_channels();
|
||||||
|
}
|
||||||
|
|
||||||
|
SampleChannels Si4713Component::get_digital_channels() { return (SampleChannels) this->digital_input_format_.IMONO; }
|
||||||
|
|
||||||
|
void Si4713Component::set_digital_mode(DigitalMode value) {
|
||||||
|
CHECK_ENUM(value)
|
||||||
|
this->digital_input_format_.IMODE = (uint16_t) value;
|
||||||
|
this->set_prop(this->digital_input_format_);
|
||||||
|
this->publish_digital_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
DigitalMode Si4713Component::get_digital_mode() { return (DigitalMode) this->digital_input_format_.IMODE; }
|
||||||
|
|
||||||
|
void Si4713Component::set_digital_clock_edge(DigitalClockEdge value) {
|
||||||
|
CHECK_ENUM(value)
|
||||||
|
this->digital_input_format_.IFALL = (uint16_t) value;
|
||||||
|
this->set_prop(this->digital_input_format_);
|
||||||
|
this->publish_digital_clock_edge();
|
||||||
|
}
|
||||||
|
|
||||||
|
DigitalClockEdge Si4713Component::get_digital_clock_edge() { return (DigitalClockEdge) digital_input_format_.IFALL; }
|
||||||
|
|
||||||
|
void Si4713Component::set_pilot_enable(bool value) {
|
||||||
|
this->tx_component_enable_.PILOT = value ? 1 : 0;
|
||||||
|
this->set_prop(this->tx_component_enable_);
|
||||||
|
this->publish_pilot_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Si4713Component::get_pilot_enable() { return this->tx_component_enable_.PILOT != 0; }
|
||||||
|
|
||||||
|
void Si4713Component::set_pilot_frequency(float value) {
|
||||||
|
CHECK_FLOAT_RANGE(value, PILOT_FREQ_MIN, PILOT_FREQ_MAX)
|
||||||
|
this->tx_pilot_frequency_.FREQ =
|
||||||
|
(uint16_t) clamp((int) std::lround(value * 1000), PILOT_FREQ_RAW_MIN, PILOT_FREQ_RAW_MAX);
|
||||||
|
this->set_prop(this->tx_pilot_frequency_);
|
||||||
|
this->publish_pilot_frequency();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Si4713Component::get_pilot_frequency() { return (float) this->tx_pilot_frequency_.FREQ / 1000; }
|
||||||
|
|
||||||
|
void Si4713Component::set_pilot_deviation(float value) {
|
||||||
|
CHECK_FLOAT_RANGE(value, TXPDEV_MIN, TXPDEV_MAX)
|
||||||
|
this->tx_pilot_deviation_.TXPDEV = (uint16_t) clamp((int) std::lround(value * 100), TXPDEV_RAW_MIN, TXPDEV_RAW_MAX);
|
||||||
|
this->set_prop(this->tx_pilot_deviation_);
|
||||||
|
this->publish_pilot_deviation();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Si4713Component::get_pilot_deviation() { return (float) this->tx_pilot_deviation_.TXPDEV / 100; }
|
||||||
|
|
||||||
|
void Si4713Component::set_refclk_frequency(int value) {
|
||||||
|
CHECK_INT_RANGE(value, REFCLKF_MIN, REFCLKF_MAX)
|
||||||
|
this->refclk_freq_.REFCLKF = (uint16_t) value;
|
||||||
|
this->set_prop(this->refclk_freq_);
|
||||||
|
this->publish_refclk_frequency();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_refclk_frequency() { return this->refclk_freq_.REFCLKF; }
|
||||||
|
|
||||||
|
void Si4713Component::set_refclk_source(RefClkSource value) {
|
||||||
|
CHECK_ENUM(value)
|
||||||
|
this->refclk_prescale_.RCLKSEL = (uint16_t) value;
|
||||||
|
this->set_prop(this->refclk_prescale_);
|
||||||
|
this->publish_refclk_source();
|
||||||
|
}
|
||||||
|
|
||||||
|
RefClkSource Si4713Component::get_refclk_source() { return (RefClkSource) this->refclk_prescale_.RCLKSEL; }
|
||||||
|
|
||||||
|
void Si4713Component::set_refclk_prescaler(int value) {
|
||||||
|
CHECK_INT_RANGE(value, RCLKP_MIN, RCLKP_MAX)
|
||||||
|
this->refclk_prescale_.RCLKP = (uint16_t) value;
|
||||||
|
this->set_prop(this->refclk_freq_);
|
||||||
|
this->publish_refclk_prescaler();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_refclk_prescaler() { return (int) this->refclk_prescale_.RCLKP; }
|
||||||
|
|
||||||
|
void Si4713Component::set_acomp_enable(bool value) {
|
||||||
|
this->tx_acomp_enable_.ACEN = value ? 1 : 0;
|
||||||
|
this->set_prop(this->tx_acomp_enable_);
|
||||||
|
this->publish_acomp_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Si4713Component::get_acomp_enable() { return this->tx_acomp_enable_.ACEN != 0; }
|
||||||
|
|
||||||
|
void Si4713Component::set_acomp_threshold(int value) {
|
||||||
|
CHECK_INT_RANGE(value, ACOMP_THRESHOLD_MIN, ACOMP_THRESHOLD_MAX)
|
||||||
|
this->tx_acomp_threshold_.THRESHOLD = (int16_t) value;
|
||||||
|
this->set_prop(this->tx_acomp_threshold_);
|
||||||
|
this->publish_acomp_threshold();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_acomp_threshold() { return (int) this->tx_acomp_threshold_.THRESHOLD; }
|
||||||
|
|
||||||
|
void Si4713Component::set_acomp_attack(AcompAttack value) {
|
||||||
|
CHECK_ENUM(value)
|
||||||
|
this->tx_acomp_attack_time_.ATTACK = (uint16_t) value;
|
||||||
|
this->set_prop(this->tx_acomp_attack_time_);
|
||||||
|
this->publish_acomp_attack();
|
||||||
|
}
|
||||||
|
|
||||||
|
AcompAttack Si4713Component::get_acomp_attack() { return (AcompAttack) tx_acomp_attack_time_.ATTACK; }
|
||||||
|
|
||||||
|
void Si4713Component::set_acomp_release(AcompRelease value) {
|
||||||
|
CHECK_ENUM(value)
|
||||||
|
this->tx_acomp_release_time_.RELEASE = (uint16_t) value;
|
||||||
|
this->set_prop(this->tx_acomp_release_time_);
|
||||||
|
this->publish_acomp_release();
|
||||||
|
}
|
||||||
|
|
||||||
|
AcompRelease Si4713Component::get_acomp_release() { return (AcompRelease) this->tx_acomp_release_time_.RELEASE; }
|
||||||
|
|
||||||
|
void Si4713Component::set_acomp_gain(int value) {
|
||||||
|
CHECK_INT_RANGE(value, ACOMP_GAIN_MIN, ACOMP_GAIN_MAX)
|
||||||
|
this->tx_acomp_gain_.GAIN = (int16_t) value;
|
||||||
|
this->set_prop(this->tx_acomp_gain_);
|
||||||
|
this->publish_acomp_gain();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_acomp_gain() { return (int) this->tx_acomp_gain_.GAIN; }
|
||||||
|
|
||||||
|
void Si4713Component::set_acomp_preset(AcompPreset value) {
|
||||||
|
CHECK_ENUM(value)
|
||||||
|
this->tx_acomp_preset_ = value;
|
||||||
|
switch (value) {
|
||||||
|
case AcompPreset::ACOMP_MINIMAL:
|
||||||
|
this->set_acomp_threshold(-40);
|
||||||
|
this->set_acomp_attack(AcompAttack::ATTACK_50MS);
|
||||||
|
this->set_acomp_release(AcompRelease::RELEASE_100MS);
|
||||||
|
this->set_acomp_gain(15);
|
||||||
|
break;
|
||||||
|
case AcompPreset::ACOMP_AGGRESSIVE:
|
||||||
|
this->set_acomp_threshold(-15);
|
||||||
|
this->set_acomp_attack(AcompAttack::ATTACK_05MS);
|
||||||
|
this->set_acomp_release(AcompRelease::RELEASE_1000MS);
|
||||||
|
this->set_acomp_gain(5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->publish_acomp_preset();
|
||||||
|
}
|
||||||
|
|
||||||
|
AcompPreset Si4713Component::get_acomp_preset() { return this->tx_acomp_preset_; }
|
||||||
|
|
||||||
|
void Si4713Component::set_limiter_enable(bool value) {
|
||||||
|
this->tx_acomp_enable_.LIMITEN = value ? 1 : 0;
|
||||||
|
this->set_prop(this->tx_acomp_enable_);
|
||||||
|
this->publish_limiter_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Si4713Component::get_limiter_enable() { return this->tx_acomp_enable_.LIMITEN != 0; }
|
||||||
|
|
||||||
|
void Si4713Component::set_limiter_release_time(float value) {
|
||||||
|
CHECK_FLOAT_RANGE(value, LMITERTC_MIN, LMITERTC_MAX)
|
||||||
|
this->tx_limiter_releasee_time_.LMITERTC =
|
||||||
|
(uint16_t) clamp((int) std::lround(512.0f / value), LMITERTC_RAW_MIN, LMITERTC_RAW_MAX);
|
||||||
|
this->set_prop(this->tx_limiter_releasee_time_);
|
||||||
|
this->publish_limiter_release_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
float Si4713Component::get_limiter_release_time() { return (float) 512.0f / this->tx_limiter_releasee_time_.LMITERTC; }
|
||||||
|
|
||||||
|
void Si4713Component::set_asq_overmod_enable(bool value) {
|
||||||
|
this->tx_asq_interrupt_source_.OVERMODIEN = value ? 1 : 0;
|
||||||
|
this->set_prop(this->tx_asq_interrupt_source_);
|
||||||
|
this->publish_asq_overmod_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Si4713Component::get_asq_overmod_enable() { return this->tx_asq_interrupt_source_.OVERMODIEN != 0; }
|
||||||
|
|
||||||
|
void Si4713Component::set_asq_iall_enable(bool value) {
|
||||||
|
this->tx_asq_interrupt_source_.IALLIEN = value ? 1 : 0;
|
||||||
|
this->set_prop(this->tx_asq_interrupt_source_);
|
||||||
|
this->publish_asq_iall_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Si4713Component::get_asq_iall_enable() { return this->tx_asq_interrupt_source_.IALLIEN != 0; }
|
||||||
|
|
||||||
|
void Si4713Component::set_asq_ialh_enable(bool value) {
|
||||||
|
this->tx_asq_interrupt_source_.IALHIEN = value ? 1 : 0;
|
||||||
|
this->set_prop(this->tx_asq_interrupt_source_);
|
||||||
|
this->publish_asq_ialh_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Si4713Component::get_asq_ialh_enable() { return this->tx_asq_interrupt_source_.IALHIEN != 0; }
|
||||||
|
|
||||||
|
void Si4713Component::set_asq_level_low(int value) {
|
||||||
|
CHECK_INT_RANGE(value, IALTH_MIN, IALTH_MAX)
|
||||||
|
this->tx_asq_level_low_.IALLTH = (int8_t) value;
|
||||||
|
this->set_prop(this->tx_asq_level_low_);
|
||||||
|
this->publish_asq_level_low();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_asq_level_low() { return (int) this->tx_asq_level_low_.IALLTH; }
|
||||||
|
|
||||||
|
void Si4713Component::set_asq_duration_low(int value) {
|
||||||
|
CHECK_INT_RANGE(value, IALDUR_MIN, IALDUR_MAX)
|
||||||
|
this->tx_asq_duration_low_.IALLDUR = (uint16_t) value;
|
||||||
|
this->set_prop(this->tx_asq_duration_low_);
|
||||||
|
this->publish_asq_duration_low();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_asq_duration_low() { return (int) this->tx_asq_duration_low_.IALLDUR; }
|
||||||
|
|
||||||
|
void Si4713Component::set_asq_level_high(int value) {
|
||||||
|
CHECK_INT_RANGE(value, IALTH_MIN, IALTH_MAX)
|
||||||
|
this->tx_asq_level_high_.IALHTH = (int8_t) value;
|
||||||
|
this->set_prop(this->tx_asq_level_high_);
|
||||||
|
this->publish_asq_level_high();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_asq_level_high() { return (int) this->tx_asq_level_high_.IALHTH; }
|
||||||
|
|
||||||
|
void Si4713Component::set_asq_duration_high(int value) {
|
||||||
|
CHECK_INT_RANGE(value, IALDUR_MIN, IALDUR_MAX)
|
||||||
|
this->tx_asq_duration_high_.IALHDUR = (uint16_t) value;
|
||||||
|
this->set_prop(this->tx_asq_duration_high_);
|
||||||
|
this->publish_asq_duration_high();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Si4713Component::get_asq_duration_high() { return (int) this->tx_asq_duration_high_.IALHDUR; }
|
||||||
|
|
||||||
void Si4713Component::set_rds_enable(bool value) {
|
void Si4713Component::set_rds_enable(bool value) {
|
||||||
// TODO
|
this->tx_component_enable_.RDS = value ? 0 : 1;
|
||||||
|
this->set_prop(this->tx_component_enable_);
|
||||||
this->publish_rds_enable();
|
this->publish_rds_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Si4713Component::get_rds_enable() {
|
bool Si4713Component::get_rds_enable() { return this->tx_component_enable_.RDS != 0; }
|
||||||
// return this->state_.RDSEN == 1;
|
|
||||||
return false;
|
void Si4713Component::set_rds_deviation(float value) {
|
||||||
|
CHECK_FLOAT_RANGE(value, TXRDEV_MIN, TXRDEV_MAX)
|
||||||
|
this->tx_rds_deviation_.TXRDEV = (uint16_t) clamp((int) std::lround(value * 100), TXRDEV_RAW_MIN, TXRDEV_RAW_MAX);
|
||||||
|
this->set_prop(this->tx_rds_deviation_);
|
||||||
|
this->publish_rds_deviation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Si4713Component::get_rds_deviation() { return (float) this->tx_rds_deviation_.TXRDEV / 100; }
|
||||||
|
|
||||||
void Si4713Component::set_rds_station(const std::string &value) {
|
void Si4713Component::set_rds_station(const std::string &value) {
|
||||||
this->rds_station_ = value;
|
this->rds_station_ = value;
|
||||||
this->rds_station_pos_ = 0;
|
// this->rds_station_pos_ = 0;
|
||||||
if (this->rds_station_.size() > RDS_STATION_MAX) {
|
CHECK_TEXT_RANGE(this->rds_station_, RDS_STATION_MAX)
|
||||||
ESP_LOGW(TAG, "rds station too long '%s' (max %d characters)", value.c_str(), RDS_STATION_MAX);
|
|
||||||
this->rds_station_.resize(RDS_STATION_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->publish_rds_station();
|
this->publish_rds_station();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Si4713Component::set_rds_text(const std::string &value) {
|
void Si4713Component::set_rds_text(const std::string &value) {
|
||||||
this->rds_text_ = value;
|
this->rds_text_ = value;
|
||||||
this->rds_text_pos_ = 0;
|
CHECK_TEXT_RANGE(this->rds_text_, RDS_TEXT_MAX)
|
||||||
if (this->rds_text_.size() > RDS_TEXT_MAX) {
|
|
||||||
ESP_LOGW(TAG, "rds text to long '%s' (max %d characters)", value.c_str(), RDS_TEXT_MAX);
|
|
||||||
this->rds_text_.resize(RDS_TEXT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->publish_rds_text();
|
this->publish_rds_text();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Si4713Component::set_gpio(uint8_t pin, bool value) {
|
void Si4713Component::set_gpio(uint8_t pin, bool value) {
|
||||||
if (pin > 2) {
|
if (pin > 2) {
|
||||||
ESP_LOGE(TAG, "set_gpio(%d, %d) invalid pin number, 0 to 2", pin, value ? 1 : 0);
|
ESP_LOGE(TAG, "%s(%d, %d) invalid pin number (0 to 2)", __func__, pin, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ESP_LOGD(TAG, "set_gpio(%d, %d)", pin, value ? 1 : 0);
|
|
||||||
this->gpio_[pin] = value ? 1 : 0;
|
this->gpio_[pin] = value ? 1 : 0;
|
||||||
this->send_cmd(CmdGpioCtl(this->gpio_[0], this->gpio_[1], this->gpio_[2]));
|
this->send_cmd(CmdGpioSet(this->gpio_[0], this->gpio_[1], this->gpio_[2]));
|
||||||
|
|
||||||
this->publish_gpio(pin);
|
this->publish_gpio(pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Si4713Component::get_gpio(uint8_t pin) {
|
bool Si4713Component::get_gpio(uint8_t pin) {
|
||||||
if (pin > 2) {
|
if (pin > 2) {
|
||||||
ESP_LOGE(TAG, "get_gpio(%d) invalid pin number, 0 to 2", pin);
|
ESP_LOGE(TAG, "%s(%d) invalid pin number (0 to 2)", __func__, pin);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this->gpio_[pin];
|
return this->gpio_[pin] != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// publish
|
// publish
|
||||||
|
|
||||||
void Si4713Component::publish_() {
|
|
||||||
// this->publish(this->_sensor_, this->state_.);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Si4713Component::publish_chip_id() { this->publish(this->chip_id_text_sensor_, this->chip_id_); }
|
|
||||||
|
|
||||||
void Si4713Component::publish_frequency() { this->publish(this->frequency_number_, this->get_frequency()); }
|
|
||||||
|
|
||||||
void Si4713Component::publish_mute() { this->publish(this->mute_switch_, this->get_mute()); }
|
void Si4713Component::publish_mute() { this->publish(this->mute_switch_, this->get_mute()); }
|
||||||
|
|
||||||
void Si4713Component::publish_mono() { this->publish(this->mono_switch_, this->get_mono()); }
|
void Si4713Component::publish_mono() { this->publish(this->mono_switch_, this->get_mono()); }
|
||||||
|
|
||||||
|
void Si4713Component::publish_pre_emphasis() {
|
||||||
|
this->publish(this->pre_emphasis_select_, (size_t) this->get_pre_emphasis());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_frequency() { this->publish(this->frequency_number_, this->get_frequency()); }
|
||||||
|
|
||||||
|
void Si4713Component::publish_audio_deviation() {
|
||||||
|
this->publish(this->audio_deviation_number_, this->get_audio_deviation());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_power() { this->publish(this->power_number_, this->get_power()); }
|
||||||
|
|
||||||
|
void Si4713Component::publish_antcap() { this->publish(this->antcap_number_, this->get_antcap()); }
|
||||||
|
|
||||||
|
void Si4713Component::publish_analog_level() { this->publish(this->analog_level_number_, this->get_analog_level()); }
|
||||||
|
|
||||||
|
void Si4713Component::publish_analog_attenuation() {
|
||||||
|
this->publish(this->analog_attenuation_select_, (size_t) this->get_analog_attenuation());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_digital_sample_bits() {
|
||||||
|
this->publish(this->digital_sample_bits_select_, (size_t) this->get_digital_sample_bits());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_digital_sample_rate() {
|
||||||
|
this->publish(this->digital_sample_rate_number_, this->get_digital_sample_rate());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_digital_channels() {
|
||||||
|
this->publish(this->digital_channels_select_, (size_t) this->get_digital_channels());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_digital_mode() {
|
||||||
|
this->publish(this->digital_mode_select_, (size_t) this->get_digital_mode());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_digital_clock_edge() {
|
||||||
|
this->publish(this->digital_clock_edge_select_, (size_t) this->get_digital_clock_edge());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_pilot_enable() { this->publish(this->pilot_enable_switch_, this->get_pilot_enable()); }
|
||||||
|
|
||||||
|
void Si4713Component::publish_pilot_frequency() {
|
||||||
|
this->publish(this->pilot_frequency_number_, this->get_pilot_frequency());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_pilot_deviation() {
|
||||||
|
this->publish(this->pilot_deviation_number_, this->get_pilot_deviation());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_refclk_frequency() {
|
||||||
|
this->publish(this->refclk_frequency_number_, this->get_refclk_frequency());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_refclk_source() {
|
||||||
|
this->publish(this->refclk_source_select_, (size_t) this->get_refclk_source());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_refclk_prescaler() {
|
||||||
|
this->publish(this->refclk_prescaler_number_, this->get_refclk_prescaler());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_acomp_enable() { this->publish(this->acomp_enable_switch_, this->get_acomp_enable()); }
|
||||||
|
|
||||||
|
void Si4713Component::publish_acomp_threshold() {
|
||||||
|
this->publish(this->acomp_threshold_number_, this->get_acomp_threshold());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_acomp_attack() {
|
||||||
|
this->publish(this->acomp_attack_select_, (size_t) this->get_acomp_attack());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_acomp_release() {
|
||||||
|
this->publish(this->acomp_release_select_, (size_t) this->get_acomp_release());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_acomp_gain() { this->publish(this->acomp_gain_number_, this->get_acomp_gain()); }
|
||||||
|
|
||||||
|
void Si4713Component::publish_acomp_preset() {
|
||||||
|
this->publish(this->acomp_preset_select_, (size_t) this->get_acomp_preset());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_limiter_enable() {
|
||||||
|
this->publish(this->limiter_enable_switch_, this->get_limiter_enable());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_limiter_release_time() {
|
||||||
|
this->publish(this->limiter_release_time_number_, this->get_limiter_release_time());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_asq_overmod_enable() {
|
||||||
|
this->publish(this->asq_overmod_enable_switch_, this->get_asq_overmod_enable());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_asq_iall_enable() {
|
||||||
|
this->publish(this->asq_iall_enable_switch_, this->get_asq_iall_enable());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_asq_ialh_enable() {
|
||||||
|
this->publish(this->asq_ialh_enable_switch_, this->get_asq_ialh_enable());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_asq_level_low() { this->publish(this->asq_level_low_number_, this->get_asq_level_low()); }
|
||||||
|
|
||||||
|
void Si4713Component::publish_asq_duration_low() {
|
||||||
|
this->publish(this->asq_duration_low_number_, this->get_asq_duration_low());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_asq_level_high() {
|
||||||
|
this->publish(this->asq_level_high_number_, this->get_asq_level_high());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_asq_duration_high() {
|
||||||
|
this->publish(this->asq_duration_high_number_, this->get_asq_duration_high());
|
||||||
|
}
|
||||||
|
|
||||||
void Si4713Component::publish_rds_enable() { this->publish(this->rds_enable_switch_, this->get_rds_enable()); }
|
void Si4713Component::publish_rds_enable() { this->publish(this->rds_enable_switch_, this->get_rds_enable()); }
|
||||||
|
|
||||||
|
void Si4713Component::publish_rds_deviation() { this->publish(this->rds_deviation_number_, this->get_rds_deviation()); }
|
||||||
|
|
||||||
void Si4713Component::publish_rds_station() { this->publish(this->rds_station_text_, this->rds_station_); }
|
void Si4713Component::publish_rds_station() { this->publish(this->rds_station_text_, this->rds_station_); }
|
||||||
|
|
||||||
void Si4713Component::publish_rds_text() { this->publish(this->rds_text_text_, this->rds_text_); }
|
void Si4713Component::publish_rds_text() { this->publish(this->rds_text_text_, this->rds_text_); }
|
||||||
|
@ -442,19 +847,21 @@ void Si4713Component::publish_rds_text() { this->publish(this->rds_text_text_, t
|
||||||
void Si4713Component::publish_gpio(uint8_t pin) {
|
void Si4713Component::publish_gpio(uint8_t pin) {
|
||||||
switch (pin) {
|
switch (pin) {
|
||||||
case 0:
|
case 0:
|
||||||
this->publish(this->gpio1_switch_, this->gpio_[pin]);
|
this->publish(this->gpio1_switch_, this->gpio_[pin] != 0);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
this->publish(this->gpio2_switch_, this->gpio_[pin]);
|
this->publish(this->gpio2_switch_, this->gpio_[pin] != 0);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
this->publish(this->gpio3_switch_, this->gpio_[pin]);
|
this->publish(this->gpio3_switch_, this->gpio_[pin] != 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Si4713Component::publish_chip_id() { this->publish(this->chip_id_text_sensor_, this->chip_id_); }
|
||||||
|
|
||||||
void Si4713Component::publish(text_sensor::TextSensor *s, const std::string &state) {
|
void Si4713Component::publish(text_sensor::TextSensor *s, const std::string &state) {
|
||||||
if (s != nullptr) {
|
if (s != nullptr) {
|
||||||
if (!s->has_state() || s->state != state) {
|
if (!s->has_state() || s->state != state) {
|
||||||
|
|
|
@ -29,16 +29,88 @@ class Si4713Component : public PollingComponent, public i2c::I2CDevice {
|
||||||
std::string chip_id_;
|
std::string chip_id_;
|
||||||
InternalGPIOPin *reset_pin_;
|
InternalGPIOPin *reset_pin_;
|
||||||
bool reset_;
|
bool reset_;
|
||||||
bool gpio_[3];
|
|
||||||
/*
|
|
||||||
union {
|
|
||||||
struct Si4713State state_;
|
|
||||||
uint8_t regs_[sizeof(struct Si4713State)];
|
|
||||||
};
|
|
||||||
|
|
||||||
void write_reg_(uint8_t addr);
|
// config
|
||||||
bool read_reg_(uint8_t addr);
|
|
||||||
|
OpMode op_mode_;
|
||||||
|
uint16_t frequency_;
|
||||||
|
uint8_t power_;
|
||||||
|
uint8_t antcap_;
|
||||||
|
PropTxComponentEnable tx_component_enable_;
|
||||||
|
PropTxAudioDeviation tx_audio_deviation_;
|
||||||
|
PropTxPreEmphasis tx_pre_emphasis_;
|
||||||
|
PropTxPilotFrequency tx_pilot_frequency_;
|
||||||
|
PropTxPilotDeviation tx_pilot_deviation_;
|
||||||
|
PropTxLineInputLevel tx_line_input_level_;
|
||||||
|
PropTxLineInputMute tx_line_input_mute_;
|
||||||
|
PropDigitalInputFormat digital_input_format_;
|
||||||
|
PropDigitalInputSampleRate digital_input_sample_rate_;
|
||||||
|
PropRefClkFreq refclk_freq_;
|
||||||
|
PropRefClkPreScale refclk_prescale_;
|
||||||
|
PropTxAcompEnable tx_acomp_enable_;
|
||||||
|
PropTxAcompThreshold tx_acomp_threshold_;
|
||||||
|
PropTxAcompAttackTime tx_acomp_attack_time_;
|
||||||
|
PropTxAcompReleaseTime tx_acomp_release_time_;
|
||||||
|
AcompPreset tx_acomp_preset_;
|
||||||
|
PropTxAcompGain tx_acomp_gain_;
|
||||||
|
PropTxLimiterReleaseTime tx_limiter_releasee_time_;
|
||||||
|
PropTxAsqInterruptSource tx_asq_interrupt_source_;
|
||||||
|
PropTxAsqLevelLow tx_asq_level_low_;
|
||||||
|
PropTxAsqDurationLow tx_asq_duration_low_;
|
||||||
|
PropTxAsqLevelHigh tx_asq_level_high_;
|
||||||
|
PropTxAsqDurationHigh tx_asq_duration_high_;
|
||||||
|
PropTxRdsDeviation tx_rds_deviation_;
|
||||||
|
uint8_t gpio_[3];
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
/*
|
||||||
|
// general
|
||||||
|
op_mode: Analog / Analog, Digital
|
||||||
|
mute: False
|
||||||
|
mono: False
|
||||||
|
pre_emphasis: 75us / 75us, 50us, Disabled, Reserved
|
||||||
|
// tune
|
||||||
|
frequency: 87.50 (MHz) / 0.05
|
||||||
|
audio_deviation: 68.25 (kHz) 0 to 90 / .01
|
||||||
|
power: 115 (dBuV) 88 to 115 / 1
|
||||||
|
antcap: 0 (auto) 0 to 191 / 1
|
||||||
|
// line input
|
||||||
|
line_level: 636 (mVPK) / ? to ?
|
||||||
|
line_attenuation: 60 (kOhm) / 190, 301, 416, 636 mV or 396, 100, 74, 60 kOhm
|
||||||
|
// digital input
|
||||||
|
digital_sample_rate: 44100 (Hz) / 32000 to 48000
|
||||||
|
digital_sample_precision: 16 (bits) / 16, 20, 24, 8
|
||||||
|
digital_channels: 0 / 0 stereo 1 mono
|
||||||
|
digital_mode: Default / Default, I2S, Left-justified, MSB at 1st DCLK rising edge after DFS Pulse, MSB ... 2nd ...
|
||||||
|
// stereo
|
||||||
|
pilot_enable: True
|
||||||
|
pilot_frequency: 19000 (Hz) 0 to 19000 / 1
|
||||||
|
pilot_deviation: 6750 (Hz) 0 to 90000 / 1
|
||||||
|
// refclk
|
||||||
|
refclkf: 32768 (Hz) 31130 to 34406 / 1
|
||||||
|
rclksel: RCLK / RCLK, DCLK
|
||||||
|
rclkp: 1
|
||||||
|
// compressor
|
||||||
|
acomp_enable: False
|
||||||
|
acomp_threshold: -40 (dBFS) -40 to 0 / 1
|
||||||
|
acomp_attack: 0.5 (ms) 0.5 to 5 / .5
|
||||||
|
acomp_release: 1000 (ms) / 100, 200, 350, 525, 1000
|
||||||
|
acomp_gain: 15 (dB) / 0 to 20
|
||||||
|
acomp_preset:
|
||||||
|
Disabled => acomp_enable: False
|
||||||
|
Minimal => acomp_enable: True, acomp_threshold: -40, acomp_attack: 5, acomp_release: 100, acomp_gain: 15
|
||||||
|
Aggressive => acomp_enable: True, acomp_threshold: -15, acomp_attack: 0.5, acomp_release: 1000, acomp_gain: 5
|
||||||
|
// limiter
|
||||||
|
limiter_enable: True
|
||||||
|
limiter_release_time: 5.01 (ms) / 5 = 102.39 ms .. 2000 = 0.25 ms
|
||||||
|
// rds
|
||||||
|
rds_enable: False
|
||||||
|
rds_deviation: 2 (kHz) 0 to 7.5 / .01
|
||||||
|
rds_station:
|
||||||
|
rds_text:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool send_cmd(const void *cmd, size_t cmd_size, void *res, size_t res_size);
|
bool send_cmd(const void *cmd, size_t cmd_size, void *res, size_t res_size);
|
||||||
|
|
||||||
template<typename CMD> bool send_cmd(const CMD &cmd) {
|
template<typename CMD> bool send_cmd(const CMD &cmd) {
|
||||||
|
@ -66,34 +138,117 @@ class Si4713Component : public PollingComponent, public i2c::I2CDevice {
|
||||||
|
|
||||||
std::string rds_station_;
|
std::string rds_station_;
|
||||||
std::string rds_text_;
|
std::string rds_text_;
|
||||||
uint8_t rds_station_pos_;
|
|
||||||
uint8_t rds_text_pos_;
|
|
||||||
uint8_t rds_upd_;
|
|
||||||
|
|
||||||
void rds_update_();
|
void rds_update_();
|
||||||
|
|
||||||
SUB_TEXT_SENSOR(chip_id)
|
bool reset();
|
||||||
|
bool power_up();
|
||||||
|
bool power_down();
|
||||||
|
bool detect_chip_id();
|
||||||
|
bool tune_freq(uint16_t freq);
|
||||||
|
bool tune_power(uint8_t power = 0, uint8_t antcap = 0);
|
||||||
|
bool tune_wait();
|
||||||
|
|
||||||
// TODO: sensors TX_TUNE_STATUS / FREQ, RFuV, ANTCAP, NL
|
// TODO: sensors TX_TUNE_STATUS / FREQ, RFuV, ANTCAP, NL
|
||||||
// TODO: sensors TX_ASQ_STATUS / OVERMOD, IALH, IALL, INLEVEL
|
// TODO: sensors TX_ASQ_STATUS / OVERMOD, IALH, IALL, INLEVEL
|
||||||
SUB_NUMBER(frequency)
|
|
||||||
|
// general config
|
||||||
SUB_SWITCH(mute)
|
SUB_SWITCH(mute)
|
||||||
SUB_SWITCH(mono)
|
SUB_SWITCH(mono)
|
||||||
|
SUB_SELECT(pre_emphasis)
|
||||||
|
// tuner
|
||||||
|
SUB_NUMBER(frequency)
|
||||||
|
SUB_NUMBER(audio_deviation)
|
||||||
|
SUB_NUMBER(power)
|
||||||
|
SUB_NUMBER(antcap)
|
||||||
|
// analog
|
||||||
|
SUB_NUMBER(analog_level)
|
||||||
|
SUB_SELECT(analog_attenuation)
|
||||||
|
// digital
|
||||||
|
SUB_NUMBER(digital_sample_rate)
|
||||||
|
SUB_SELECT(digital_sample_bits)
|
||||||
|
SUB_SELECT(digital_channels)
|
||||||
|
SUB_SELECT(digital_mode)
|
||||||
|
SUB_SELECT(digital_clock_edge)
|
||||||
|
// pilot
|
||||||
|
SUB_SWITCH(pilot_enable)
|
||||||
|
SUB_NUMBER(pilot_frequency)
|
||||||
|
SUB_NUMBER(pilot_deviation)
|
||||||
|
// refclk
|
||||||
|
SUB_NUMBER(refclk_frequency)
|
||||||
|
SUB_SELECT(refclk_source)
|
||||||
|
SUB_NUMBER(refclk_prescaler)
|
||||||
|
// compressor
|
||||||
|
SUB_SWITCH(acomp_enable)
|
||||||
|
SUB_NUMBER(acomp_threshold)
|
||||||
|
SUB_SELECT(acomp_attack)
|
||||||
|
SUB_SELECT(acomp_release)
|
||||||
|
SUB_NUMBER(acomp_gain)
|
||||||
|
SUB_SELECT(acomp_preset)
|
||||||
|
// limiter
|
||||||
|
SUB_SWITCH(limiter_enable)
|
||||||
|
SUB_NUMBER(limiter_release_time)
|
||||||
|
// asq
|
||||||
|
SUB_SWITCH(asq_overmod_enable)
|
||||||
|
SUB_SWITCH(asq_iall_enable)
|
||||||
|
SUB_SWITCH(asq_ialh_enable)
|
||||||
|
SUB_NUMBER(asq_level_low)
|
||||||
|
SUB_NUMBER(asq_duration_low)
|
||||||
|
SUB_NUMBER(asq_level_high)
|
||||||
|
SUB_NUMBER(asq_duration_high)
|
||||||
|
// rds
|
||||||
SUB_SWITCH(rds_enable)
|
SUB_SWITCH(rds_enable)
|
||||||
|
SUB_NUMBER(rds_deviation)
|
||||||
SUB_TEXT(rds_station)
|
SUB_TEXT(rds_station)
|
||||||
SUB_TEXT(rds_text)
|
SUB_TEXT(rds_text)
|
||||||
|
// output
|
||||||
SUB_SWITCH(gpio1)
|
SUB_SWITCH(gpio1)
|
||||||
SUB_SWITCH(gpio2)
|
SUB_SWITCH(gpio2)
|
||||||
SUB_SWITCH(gpio3)
|
SUB_SWITCH(gpio3)
|
||||||
|
// sensors
|
||||||
|
SUB_TEXT_SENSOR(chip_id)
|
||||||
|
|
||||||
void publish_();
|
|
||||||
void publish_chip_id();
|
|
||||||
void publish_frequency();
|
|
||||||
void publish_mute();
|
void publish_mute();
|
||||||
void publish_mono();
|
void publish_mono();
|
||||||
|
void publish_pre_emphasis();
|
||||||
|
void publish_frequency();
|
||||||
|
void publish_audio_deviation();
|
||||||
|
void publish_power();
|
||||||
|
void publish_antcap();
|
||||||
|
void publish_analog_level();
|
||||||
|
void publish_analog_attenuation();
|
||||||
|
void publish_digital_sample_rate();
|
||||||
|
void publish_digital_sample_bits();
|
||||||
|
void publish_digital_channels();
|
||||||
|
void publish_digital_mode();
|
||||||
|
void publish_digital_clock_edge();
|
||||||
|
void publish_pilot_enable();
|
||||||
|
void publish_pilot_frequency();
|
||||||
|
void publish_pilot_deviation();
|
||||||
|
void publish_refclk_frequency();
|
||||||
|
void publish_refclk_source();
|
||||||
|
void publish_refclk_prescaler();
|
||||||
|
void publish_acomp_enable();
|
||||||
|
void publish_acomp_threshold();
|
||||||
|
void publish_acomp_attack();
|
||||||
|
void publish_acomp_release();
|
||||||
|
void publish_acomp_gain();
|
||||||
|
void publish_acomp_preset();
|
||||||
|
void publish_limiter_enable();
|
||||||
|
void publish_limiter_release_time();
|
||||||
|
void publish_asq_overmod_enable();
|
||||||
|
void publish_asq_iall_enable();
|
||||||
|
void publish_asq_ialh_enable();
|
||||||
|
void publish_asq_level_low();
|
||||||
|
void publish_asq_duration_low();
|
||||||
|
void publish_asq_level_high();
|
||||||
|
void publish_asq_duration_high();
|
||||||
void publish_rds_enable();
|
void publish_rds_enable();
|
||||||
|
void publish_rds_deviation();
|
||||||
void publish_rds_station();
|
void publish_rds_station();
|
||||||
void publish_rds_text();
|
void publish_rds_text();
|
||||||
void publish_gpio(uint8_t pin);
|
void publish_gpio(uint8_t pin);
|
||||||
|
void publish_chip_id();
|
||||||
void publish(sensor::Sensor *s, float state);
|
void publish(sensor::Sensor *s, float state);
|
||||||
void publish(text_sensor::TextSensor *s, const std::string &state);
|
void publish(text_sensor::TextSensor *s, const std::string &state);
|
||||||
void publish(number::Number *n, float state);
|
void publish(number::Number *n, float state);
|
||||||
|
@ -110,23 +265,84 @@ class Si4713Component : public PollingComponent, public i2c::I2CDevice {
|
||||||
void update() override;
|
void update() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
|
|
||||||
bool reset();
|
// non-mutable (opmode might be)
|
||||||
bool power_up();
|
|
||||||
bool power_down();
|
|
||||||
bool detect_chip_id();
|
|
||||||
bool tune_freq(uint16_t freq);
|
|
||||||
bool tune_power(uint8_t power = 0, uint8_t antcap = 0);
|
|
||||||
bool tune_wait();
|
|
||||||
|
|
||||||
void set_reset_pin(InternalGPIOPin *pin);
|
void set_reset_pin(InternalGPIOPin *pin);
|
||||||
void set_frequency(float value);
|
void set_op_mode(OpMode value);
|
||||||
float get_frequency();
|
|
||||||
void set_mute(bool value);
|
void set_mute(bool value);
|
||||||
bool get_mute();
|
bool get_mute();
|
||||||
void set_mono(bool value);
|
void set_mono(bool value);
|
||||||
bool get_mono();
|
bool get_mono();
|
||||||
|
void set_pre_emphasis(PreEmphasis value);
|
||||||
|
PreEmphasis get_pre_emphasis();
|
||||||
|
void set_frequency(float value);
|
||||||
|
float get_frequency();
|
||||||
|
void set_audio_deviation(float value);
|
||||||
|
float get_audio_deviation();
|
||||||
|
void set_power(int value);
|
||||||
|
int get_power();
|
||||||
|
void set_antcap(int value);
|
||||||
|
int get_antcap();
|
||||||
|
void set_analog_level(int value);
|
||||||
|
int get_analog_level();
|
||||||
|
void set_analog_attenuation(LineAttenuation value);
|
||||||
|
LineAttenuation get_analog_attenuation();
|
||||||
|
void set_digital_sample_rate(int value);
|
||||||
|
int get_digital_sample_rate();
|
||||||
|
void set_digital_sample_bits(SampleBits value);
|
||||||
|
SampleBits get_digital_sample_bits();
|
||||||
|
void set_digital_channels(SampleChannels value);
|
||||||
|
SampleChannels get_digital_channels();
|
||||||
|
void set_digital_mode(DigitalMode value);
|
||||||
|
DigitalMode get_digital_mode();
|
||||||
|
void set_digital_clock_edge(DigitalClockEdge value);
|
||||||
|
DigitalClockEdge get_digital_clock_edge();
|
||||||
|
void set_pilot_enable(bool value);
|
||||||
|
bool get_pilot_enable();
|
||||||
|
void set_pilot_frequency(float value);
|
||||||
|
float get_pilot_frequency();
|
||||||
|
void set_pilot_deviation(float value);
|
||||||
|
float get_pilot_deviation();
|
||||||
|
void set_refclk_frequency(int value);
|
||||||
|
int get_refclk_frequency();
|
||||||
|
void set_refclk_source(RefClkSource value);
|
||||||
|
RefClkSource get_refclk_source();
|
||||||
|
void set_refclk_prescaler(int value);
|
||||||
|
int get_refclk_prescaler();
|
||||||
|
void set_acomp_enable(bool value);
|
||||||
|
bool get_acomp_enable();
|
||||||
|
void set_acomp_threshold(int value);
|
||||||
|
int get_acomp_threshold();
|
||||||
|
void set_acomp_attack(AcompAttack value);
|
||||||
|
AcompAttack get_acomp_attack();
|
||||||
|
void set_acomp_release(AcompRelease value);
|
||||||
|
AcompRelease get_acomp_release();
|
||||||
|
void set_acomp_gain(int value);
|
||||||
|
int get_acomp_gain();
|
||||||
|
void set_acomp_preset(AcompPreset value);
|
||||||
|
AcompPreset get_acomp_preset();
|
||||||
|
void set_limiter_enable(bool value);
|
||||||
|
bool get_limiter_enable();
|
||||||
|
void set_limiter_release_time(float value);
|
||||||
|
float get_limiter_release_time();
|
||||||
|
void set_asq_overmod_enable(bool value);
|
||||||
|
bool get_asq_overmod_enable();
|
||||||
|
void set_asq_iall_enable(bool value);
|
||||||
|
bool get_asq_iall_enable();
|
||||||
|
void set_asq_ialh_enable(bool value);
|
||||||
|
bool get_asq_ialh_enable();
|
||||||
|
void set_asq_level_low(int value);
|
||||||
|
int get_asq_level_low();
|
||||||
|
void set_asq_duration_low(int value);
|
||||||
|
int get_asq_duration_low();
|
||||||
|
void set_asq_level_high(int value);
|
||||||
|
int get_asq_level_high();
|
||||||
|
void set_asq_duration_high(int value);
|
||||||
|
int get_asq_duration_high();
|
||||||
void set_rds_enable(bool value);
|
void set_rds_enable(bool value);
|
||||||
bool get_rds_enable();
|
bool get_rds_enable();
|
||||||
|
void set_rds_deviation(float value);
|
||||||
|
float get_rds_deviation();
|
||||||
void set_rds_station(const std::string &value);
|
void set_rds_station(const std::string &value);
|
||||||
void set_rds_text(const std::string &value);
|
void set_rds_text(const std::string &value);
|
||||||
void set_gpio(uint8_t pin, bool value);
|
void set_gpio(uint8_t pin, bool value);
|
||||||
|
|
|
@ -5,11 +5,140 @@ namespace si4713 {
|
||||||
|
|
||||||
static const uint8_t SI4710_STATUS_CTS = 0x80;
|
static const uint8_t SI4710_STATUS_CTS = 0x80;
|
||||||
|
|
||||||
static const float CH_FREQ_MIN = 76;
|
static const float FREQ_MIN = 76;
|
||||||
static const float CH_FREQ_MAX = 108;
|
static const float FREQ_MAX = 108;
|
||||||
|
static const int FREQ_RAW_MIN = 7600;
|
||||||
|
static const int FREQ_RAW_MAX = 10800;
|
||||||
|
static const int POWER_MIN = 88;
|
||||||
|
static const int POWER_MAX = 120;
|
||||||
|
static const int ANTCAP_MIN = 0;
|
||||||
|
static const int ANTCAP_MAX = 191;
|
||||||
|
static const int LILEVEL_MIN = 0;
|
||||||
|
static const int LILEVEL_MAX = 1023; // no max in the datasheet, only that it is 10 bits
|
||||||
|
static const int DISR_MIN = 32000;
|
||||||
|
static const int DISR_MAX = 48000;
|
||||||
|
static const float PILOT_FREQ_MIN = 0;
|
||||||
|
static const float PILOT_FREQ_MAX = 19;
|
||||||
|
static const int PILOT_FREQ_RAW_MIN = 0;
|
||||||
|
static const int PILOT_FREQ_RAW_MAX = 19000;
|
||||||
|
static const float TXADEV_MIN = 0;
|
||||||
|
static const float TXADEV_MAX = 90;
|
||||||
|
static const int TXADEV_RAW_MIN = 0;
|
||||||
|
static const int TXADEV_RAW_MAX = 9000;
|
||||||
|
static const float TXPDEV_MIN = 0;
|
||||||
|
static const float TXPDEV_MAX = 90;
|
||||||
|
static const int TXPDEV_RAW_MIN = 0;
|
||||||
|
static const int TXPDEV_RAW_MAX = 9000;
|
||||||
|
static const float TXRDEV_MIN = 0;
|
||||||
|
static const float TXRDEV_MAX = 7.5f;
|
||||||
|
static const int TXRDEV_RAW_MIN = 0;
|
||||||
|
static const int TXRDEV_RAW_MAX = 750;
|
||||||
|
static const int REFCLKF_MIN = 31130;
|
||||||
|
static const int REFCLKF_MAX = 34406;
|
||||||
|
static const int RCLKP_MIN = 1;
|
||||||
|
static const int RCLKP_MAX = 4095;
|
||||||
|
static const int ACOMP_THRESHOLD_MIN = -40;
|
||||||
|
static const int ACOMP_THRESHOLD_MAX = 0;
|
||||||
|
static const int ACOMP_GAIN_MIN = 0;
|
||||||
|
static const int ACOMP_GAIN_MAX = 20;
|
||||||
|
static const float ACOMP_ATTACK_MIN = 0.5f;
|
||||||
|
static const float ACOMP_ATTACK_MAX = 5.0f;
|
||||||
|
static const int ACOMP_ATTACK_RAW_MIN = 0;
|
||||||
|
static const int ACOMP_ATTACK_RAW_MAX = 9;
|
||||||
|
static const float LMITERTC_MIN = 0.25f;
|
||||||
|
static const float LMITERTC_MAX = 102.4f;
|
||||||
|
static const int LMITERTC_RAW_MIN = 5;
|
||||||
|
static const int LMITERTC_RAW_MAX = 2000;
|
||||||
|
static const int IALTH_MIN = -70;
|
||||||
|
static const int IALTH_MAX = 0;
|
||||||
|
static const int IALDUR_MIN = 0;
|
||||||
|
static const int IALDUR_MAX = 65535;
|
||||||
|
|
||||||
static const uint8_t RDS_STATION_MAX = 8;
|
static const uint8_t RDS_STATION_MAX = 8; // TODO
|
||||||
static const uint8_t RDS_TEXT_MAX = 64;
|
static const uint8_t RDS_TEXT_MAX = 64; // TODO
|
||||||
|
|
||||||
|
template<typename T> T GET_ENUM_LAST(T value) { return T::LAST; }
|
||||||
|
|
||||||
|
enum class OpMode {
|
||||||
|
OPMODE_ANALOG = 0b01010000, // 0x50
|
||||||
|
OPMODE_DIGITAL = 0b00001111, // 0x0F
|
||||||
|
LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class PreEmphasis {
|
||||||
|
FMPE_75US, // USA
|
||||||
|
FMPE_50US, // EU
|
||||||
|
FMPE_DISABLED,
|
||||||
|
LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class LineAttenuation {
|
||||||
|
LIATTEN_396KOHM,
|
||||||
|
LIATTEN_100KOHM,
|
||||||
|
LIATTEN_74KOHM,
|
||||||
|
LIATTEN_60KOHM,
|
||||||
|
LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SampleBits {
|
||||||
|
ISIZE_16BITS,
|
||||||
|
ISIZE_20BITS,
|
||||||
|
ISIZE_24BITS,
|
||||||
|
ISIZE_8BITS,
|
||||||
|
LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SampleChannels {
|
||||||
|
IMONO_STEREO,
|
||||||
|
IMONO_MONO,
|
||||||
|
LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DigitalMode {
|
||||||
|
IMODE_DEFAULT,
|
||||||
|
IMODE_I2S,
|
||||||
|
IMODE_LEFT_JUSTIFIED,
|
||||||
|
IMODE_MSB_AT_1ST,
|
||||||
|
IMODE_MSB_AT_2ND,
|
||||||
|
LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DigitalClockEdge {
|
||||||
|
IFALL_DCLK_RISING_EDGE,
|
||||||
|
IFALL_DCLK_FALLIBG_EDGE,
|
||||||
|
LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class RefClkSource {
|
||||||
|
RCLKSEL_RCLK,
|
||||||
|
RCLKSEL_DCLK,
|
||||||
|
LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AcompAttack {
|
||||||
|
ATTACK_05MS,
|
||||||
|
ATTACK_10MS,
|
||||||
|
ATTACK_15MS,
|
||||||
|
ATTACK_20MS,
|
||||||
|
ATTACK_25MS,
|
||||||
|
ATTACK_30MS,
|
||||||
|
ATTACK_35MS,
|
||||||
|
ATTACK_40MS,
|
||||||
|
ATTACK_45MS,
|
||||||
|
ATTACK_50MS,
|
||||||
|
LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AcompRelease {
|
||||||
|
RELEASE_100MS,
|
||||||
|
RELEASE_200MS,
|
||||||
|
RELEASE_350MS,
|
||||||
|
RELEASE_525MS,
|
||||||
|
RELEASE_1000MS,
|
||||||
|
LAST,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AcompPreset { ACOMP_MINIMAL, ACOMP_AGGRESSIVE, ACOMP_CUSTOM, LAST };
|
||||||
|
|
||||||
enum class CmdType : uint8_t {
|
enum class CmdType : uint8_t {
|
||||||
POWER_UP = 0x01, // Power up device and mode selection.
|
POWER_UP = 0x01, // Power up device and mode selection.
|
||||||
|
@ -407,11 +536,9 @@ struct ResTxTuneMeasure : ResBase {};
|
||||||
|
|
||||||
struct CmdTxTuneStatus : CmdBase {
|
struct CmdTxTuneStatus : CmdBase {
|
||||||
union {
|
union {
|
||||||
uint8_t ARG[2];
|
uint8_t ARG[1];
|
||||||
struct {
|
struct {
|
||||||
// ARG1
|
// ARG1
|
||||||
uint8_t : 8; // zero
|
|
||||||
// ARG2
|
|
||||||
uint8_t INTACK : 1; // Seek/Tune Interrupt Clear.
|
uint8_t INTACK : 1; // Seek/Tune Interrupt Clear.
|
||||||
uint8_t : 7;
|
uint8_t : 7;
|
||||||
};
|
};
|
||||||
|
@ -420,7 +547,6 @@ struct CmdTxTuneStatus : CmdBase {
|
||||||
CmdTxTuneStatus(uint8_t intack = 1) {
|
CmdTxTuneStatus(uint8_t intack = 1) {
|
||||||
this->CMD = CmdType::TX_TUNE_STATUS;
|
this->CMD = CmdType::TX_TUNE_STATUS;
|
||||||
this->ARG[0] = 0;
|
this->ARG[0] = 0;
|
||||||
this->ARG[1] = 0;
|
|
||||||
this->INTACK = intack;
|
this->INTACK = intack;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -449,11 +575,9 @@ struct ResTxTuneStatus : ResBase {
|
||||||
|
|
||||||
struct CmdTxAsqStatus : CmdBase {
|
struct CmdTxAsqStatus : CmdBase {
|
||||||
union {
|
union {
|
||||||
uint8_t ARG[2];
|
uint8_t ARG[1];
|
||||||
struct {
|
struct {
|
||||||
// ARG1
|
// ARG1
|
||||||
uint8_t : 8; // zero
|
|
||||||
// ARG2
|
|
||||||
uint8_t INTACK : 1; // Interrupt Acknowledge. Clears ASQINT, OVERMOD, IALDH, and IALDL
|
uint8_t INTACK : 1; // Interrupt Acknowledge. Clears ASQINT, OVERMOD, IALDH, and IALDL
|
||||||
uint8_t : 7;
|
uint8_t : 7;
|
||||||
};
|
};
|
||||||
|
@ -462,7 +586,6 @@ struct CmdTxAsqStatus : CmdBase {
|
||||||
CmdTxAsqStatus(uint8_t intack = 1) {
|
CmdTxAsqStatus(uint8_t intack = 1) {
|
||||||
this->CMD = CmdType::TX_ASQ_STATUS;
|
this->CMD = CmdType::TX_ASQ_STATUS;
|
||||||
this->ARG[0] = 0;
|
this->ARG[0] = 0;
|
||||||
this->ARG[1] = 0;
|
|
||||||
this->INTACK = intack;
|
this->INTACK = intack;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -472,9 +595,9 @@ struct ResTxAsqStatus : ResBase {
|
||||||
uint8_t RESP[4];
|
uint8_t RESP[4];
|
||||||
struct {
|
struct {
|
||||||
// RESP1
|
// RESP1
|
||||||
uint8_t OVERMOD : 1; // Overmodulation Detection
|
uint8_t IALL : 1; // Overmodulation Detection
|
||||||
uint8_t IALH : 1; // Input Audio Level Threshold Detect High
|
uint8_t IALH : 1; // Input Audio Level Threshold Detect High
|
||||||
uint8_t IALL : 1; // Input Audio Level Threshold Detect Low
|
uint8_t OVERMOD : 1; // Input Audio Level Threshold Detect Low
|
||||||
uint8_t : 5;
|
uint8_t : 5;
|
||||||
// RESP2
|
// RESP2
|
||||||
uint8_t : 8;
|
uint8_t : 8;
|
||||||
|
@ -673,13 +796,16 @@ struct PropDigitalInputFormat : PropBase {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
PropDigitalInputFormat(uint16_t isize = 0, uint16_t imono = 0, uint16_t imode = 0, uint16_t ifall = 0) {
|
PropDigitalInputFormat(SampleBits isize = SampleBits::ISIZE_16BITS,
|
||||||
|
SampleChannels imono = SampleChannels::IMONO_STEREO,
|
||||||
|
DigitalMode imode = DigitalMode::IMODE_DEFAULT,
|
||||||
|
DigitalClockEdge ifall = DigitalClockEdge::IFALL_DCLK_RISING_EDGE) {
|
||||||
this->PROP = PropType::DIGITAL_INPUT_FORMAT;
|
this->PROP = PropType::DIGITAL_INPUT_FORMAT;
|
||||||
this->PROPD = 0x0000;
|
this->PROPD = 0x0000;
|
||||||
this->ISIZE = isize;
|
this->ISIZE = (uint16_t) isize;
|
||||||
this->IMONO = imono;
|
this->IMONO = (uint16_t) imono;
|
||||||
this->IMODE = imode;
|
this->IMODE = (uint16_t) imode;
|
||||||
this->IFALL = ifall;
|
this->IFALL = (uint16_t) ifall;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -724,11 +850,11 @@ struct PropRefClkPreScale : PropBase {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
PropRefClkPreScale(uint16_t rclkp = 1, uint16_t rclksel = 0) {
|
PropRefClkPreScale(uint16_t rclkp = 1, RefClkSource rclksel = RefClkSource::RCLKSEL_RCLK) {
|
||||||
this->PROP = PropType::REFCLK_PRESCALE;
|
this->PROP = PropType::REFCLK_PRESCALE;
|
||||||
this->PROPD = 0x0001;
|
this->PROPD = 0x0001;
|
||||||
this->RCLKP = rclkp;
|
this->RCLKP = rclkp;
|
||||||
this->RCLKSEL = rclksel;
|
this->RCLKSEL = (uint16_t) rclksel;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -805,11 +931,11 @@ struct PropTxLineInputLevel : PropBase {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
PropTxLineInputLevel(uint16_t lilevel = 636, uint16_t liatten = 3) {
|
PropTxLineInputLevel(uint16_t lilevel = 636, LineAttenuation liatten = LineAttenuation::LIATTEN_60KOHM) {
|
||||||
this->PROP = PropType::TX_LINE_INPUT_LEVEL;
|
this->PROP = PropType::TX_LINE_INPUT_LEVEL;
|
||||||
this->PROPD = 0x327C;
|
this->PROPD = 0x327C;
|
||||||
this->LILEVEL = lilevel;
|
this->LILEVEL = lilevel;
|
||||||
this->LIATTEN = liatten;
|
this->LIATTEN = (uint16_t) liatten;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -840,10 +966,10 @@ struct PropTxPreEmphasis : PropBase {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
PropTxPreEmphasis(uint16_t fmpe = 0) {
|
PropTxPreEmphasis(PreEmphasis fmpe = PreEmphasis::FMPE_75US) {
|
||||||
this->PROP = PropType::TX_PREEMPHASIS;
|
this->PROP = PropType::TX_PREEMPHASIS;
|
||||||
this->PROPD = 0x0000;
|
this->PROPD = 0x0000;
|
||||||
this->FMPE = fmpe;
|
this->FMPE = (uint16_t) fmpe;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -920,10 +1046,10 @@ struct PropTxAcompReleaseTime : PropBase {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
PropTxAcompReleaseTime(uint16_t release = 4) {
|
PropTxAcompReleaseTime(AcompRelease release = AcompRelease::RELEASE_1000MS) {
|
||||||
this->PROP = PropType::TX_ACOMP_RELEASE_TIME;
|
this->PROP = PropType::TX_ACOMP_RELEASE_TIME;
|
||||||
this->PROPD = 0x0004;
|
this->PROPD = 0x0004;
|
||||||
this->RELEASE = release;
|
this->RELEASE = (uint16_t) release;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -978,8 +1104,8 @@ struct PropTxAsqLevelLow : PropBase {
|
||||||
union {
|
union {
|
||||||
uint16_t PROPD;
|
uint16_t PROPD;
|
||||||
struct {
|
struct {
|
||||||
uint16_t IALLTH : 8; // Input Audio Level Low Threshold (-70 to 0 dB)
|
int8_t IALLTH : 8; // Input Audio Level Low Threshold (-70 to 0 dB)
|
||||||
uint16_t : 8;
|
uint8_t : 8;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1007,8 +1133,8 @@ struct PropTxAsqLevelHigh : PropBase {
|
||||||
union {
|
union {
|
||||||
uint16_t PROPD;
|
uint16_t PROPD;
|
||||||
struct {
|
struct {
|
||||||
uint16_t IALHTH : 8; // Input Audio Level High Threshold (-70 to 0 dB)
|
int8_t IALHTH : 8; // Input Audio Level High Threshold (-70 to 0 dB)
|
||||||
uint16_t : 8;
|
uint8_t : 8;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,20 +10,36 @@ from .. import (
|
||||||
CONF_SI4713_ID,
|
CONF_SI4713_ID,
|
||||||
Si4713Component,
|
Si4713Component,
|
||||||
si4713_ns,
|
si4713_ns,
|
||||||
|
CONF_SECTION_PILOT,
|
||||||
|
CONF_SECTION_COMPRESSOR,
|
||||||
|
CONF_SECTION_LIMITER,
|
||||||
|
CONF_SECTION_ASQ,
|
||||||
|
CONF_SECTION_RDS,
|
||||||
|
CONF_SECTION_OUTPUT,
|
||||||
CONF_MUTE,
|
CONF_MUTE,
|
||||||
CONF_MONO,
|
CONF_MONO,
|
||||||
CONF_RDS_ENABLE,
|
CONF_ENABLE,
|
||||||
|
CONF_OVERMOD,
|
||||||
|
CONF_IALL,
|
||||||
|
CONF_IALH,
|
||||||
|
CONF_GPIO1,
|
||||||
|
CONF_GPIO2,
|
||||||
|
CONF_GPIO3,
|
||||||
|
ICON_SINE_WAVE,
|
||||||
ICON_VOLUME_MUTE,
|
ICON_VOLUME_MUTE,
|
||||||
ICON_EAR_HEARING,
|
ICON_EAR_HEARING,
|
||||||
ICON_FORMAT_TEXT,
|
ICON_FORMAT_TEXT,
|
||||||
)
|
)
|
||||||
|
|
||||||
CONF_GPIO1="gpio1"
|
|
||||||
CONF_GPIO2="gpio2"
|
|
||||||
CONF_GPIO3="gpio3"
|
|
||||||
|
|
||||||
MuteSwitch = si4713_ns.class_("MuteSwitch", switch.Switch)
|
MuteSwitch = si4713_ns.class_("MuteSwitch", switch.Switch)
|
||||||
MonoSwitch = si4713_ns.class_("MonoSwitch", switch.Switch)
|
MonoSwitch = si4713_ns.class_("MonoSwitch", switch.Switch)
|
||||||
|
PilotEnableSwitch = si4713_ns.class_("PilotEnableSwitch", switch.Switch)
|
||||||
|
AcompEnableSwitch = si4713_ns.class_("AcompEnableSwitch", switch.Switch)
|
||||||
|
LimiterEnableSwitch = si4713_ns.class_("LimiterEnableSwitch", switch.Switch)
|
||||||
|
AsqOvermodEnableSwitch = si4713_ns.class_("AsqOvermodEnableSwitch", switch.Switch)
|
||||||
|
AsqIallEnableSwitch = si4713_ns.class_("AsqIallEnableSwitch", switch.Switch)
|
||||||
|
AsqIalhEnableSwitch = si4713_ns.class_("AsqIalhEnableSwitch", switch.Switch)
|
||||||
|
RdsEnable = si4713_ns.class_("RdsEnable", switch.Switch)
|
||||||
RDSEnableSwitch = si4713_ns.class_("RDSEnableSwitch", switch.Switch)
|
RDSEnableSwitch = si4713_ns.class_("RDSEnableSwitch", switch.Switch)
|
||||||
GPIOSwitch = si4713_ns.class_("GPIOSwitch", switch.Switch)
|
GPIOSwitch = si4713_ns.class_("GPIOSwitch", switch.Switch)
|
||||||
|
|
||||||
|
@ -42,12 +58,70 @@ CONFIG_SCHEMA = cv.Schema(
|
||||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
icon=ICON_EAR_HEARING,
|
icon=ICON_EAR_HEARING,
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_RDS_ENABLE): switch.switch_schema(
|
cv.Optional(CONF_SECTION_PILOT): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ENABLE): switch.switch_schema(
|
||||||
|
PilotEnableSwitch,
|
||||||
|
device_class=DEVICE_CLASS_SWITCH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
icon=ICON_SINE_WAVE,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_COMPRESSOR): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ENABLE): switch.switch_schema(
|
||||||
|
AcompEnableSwitch,
|
||||||
|
device_class=DEVICE_CLASS_SWITCH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
icon=ICON_SINE_WAVE,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_LIMITER): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ENABLE): switch.switch_schema(
|
||||||
|
LimiterEnableSwitch,
|
||||||
|
device_class=DEVICE_CLASS_SWITCH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
icon=ICON_SINE_WAVE,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_ASQ): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_OVERMOD): switch.switch_schema(
|
||||||
|
AsqOvermodEnableSwitch,
|
||||||
|
device_class=DEVICE_CLASS_SWITCH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
# icon=ICON_,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_IALL): switch.switch_schema(
|
||||||
|
AsqIallEnableSwitch,
|
||||||
|
device_class=DEVICE_CLASS_SWITCH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
# icon=ICON_,
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_IALH): switch.switch_schema(
|
||||||
|
AsqIalhEnableSwitch,
|
||||||
|
device_class=DEVICE_CLASS_SWITCH,
|
||||||
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
|
# icon=ICON_,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_RDS): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_ENABLE): switch.switch_schema(
|
||||||
RDSEnableSwitch,
|
RDSEnableSwitch,
|
||||||
device_class=DEVICE_CLASS_SWITCH,
|
device_class=DEVICE_CLASS_SWITCH,
|
||||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
icon=ICON_FORMAT_TEXT,
|
icon=ICON_FORMAT_TEXT,
|
||||||
),
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
cv.Optional(CONF_SECTION_OUTPUT): cv.Schema(
|
||||||
|
{
|
||||||
cv.Optional(CONF_GPIO1): switch.switch_schema(
|
cv.Optional(CONF_GPIO1): switch.switch_schema(
|
||||||
GPIOSwitch,
|
GPIOSwitch,
|
||||||
device_class=DEVICE_CLASS_SWITCH,
|
device_class=DEVICE_CLASS_SWITCH,
|
||||||
|
@ -67,25 +141,39 @@ CONFIG_SCHEMA = cv.Schema(
|
||||||
# icon=,
|
# icon=,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def new_switch(config, id, setter):
|
async def new_switch(parent, config, id, setter):
|
||||||
if c := config.get(id):
|
if c := config.get(id):
|
||||||
s = await switch.new_switch(c)
|
s = await switch.new_switch(c)
|
||||||
await cg.register_parented(s, config[CONF_SI4713_ID])
|
await cg.register_parented(s, parent)
|
||||||
cg.add(setter(s))
|
cg.add(setter(s))
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
c = await cg.get_variable(config[CONF_SI4713_ID])
|
parent = await cg.get_variable(config[CONF_SI4713_ID])
|
||||||
await new_switch(config, CONF_MUTE, c.set_mute_switch)
|
await new_switch(parent, config, CONF_MUTE, parent.set_mute_switch)
|
||||||
await new_switch(config, CONF_MONO, c.set_mono_switch)
|
await new_switch(parent, config, CONF_MONO, parent.set_mono_switch)
|
||||||
await new_switch(config, CONF_RDS_ENABLE, c.set_rds_enable_switch)
|
if pilot_config := config.get(CONF_SECTION_PILOT):
|
||||||
s = await new_switch(config, CONF_GPIO1, c.set_gpio1_switch)
|
await new_switch(parent, pilot_config, CONF_ENABLE, parent.set_pilot_enable_switch)
|
||||||
s.set_pin(1)
|
if compressor_config := config.get(CONF_SECTION_COMPRESSOR):
|
||||||
s = await new_switch(config, CONF_GPIO2, c.set_gpio2_switch)
|
await new_switch(parent, compressor_config, CONF_ENABLE, parent.set_acomp_enable_switch)
|
||||||
s.set_pin(2)
|
if limiter_config := config.get(CONF_SECTION_LIMITER):
|
||||||
s = await new_switch(config, CONF_GPIO3, c.set_gpio3_switch)
|
await new_switch(parent, limiter_config, CONF_ENABLE, parent.set_limiter_enable_switch)
|
||||||
s.set_pin(3)
|
if asq_config := config.get(CONF_SECTION_ASQ):
|
||||||
|
await new_switch(parent, asq_config, CONF_OVERMOD, parent.set_asq_overmod_enable_switch)
|
||||||
|
await new_switch(parent, asq_config, CONF_IALL, parent.set_asq_iall_enable_switch)
|
||||||
|
await new_switch(parent, asq_config, CONF_IALH, parent.set_asq_ialh_enable_switch)
|
||||||
|
if rds_config := config.get(CONF_SECTION_RDS):
|
||||||
|
await new_switch(parent, rds_config, CONF_ENABLE, parent.set_rds_enable_switch)
|
||||||
|
if output_config := config.get(CONF_SECTION_OUTPUT):
|
||||||
|
gpio1 = await new_switch(parent, output_config, CONF_GPIO1, parent.set_gpio1_switch)
|
||||||
|
gpio2 = await new_switch(parent, output_config, CONF_GPIO2, parent.set_gpio2_switch)
|
||||||
|
gpio3 = await new_switch(parent, output_config, CONF_GPIO3, parent.set_gpio3_switch)
|
||||||
|
cg.add(gpio1.set_pin(1))
|
||||||
|
cg.add(gpio2.set_pin(2))
|
||||||
|
cg.add(gpio3.set_pin(3))
|
||||||
|
|
12
esphome/components/si4713_i2c/switch/acomp_enable_switch.cpp
Normal file
12
esphome/components/si4713_i2c/switch/acomp_enable_switch.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "acomp_enable_switch.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void AcompEnableSwitch::write_state(bool value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_acomp_enable(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/switch/acomp_enable_switch.h
Normal file
18
esphome/components/si4713_i2c/switch/acomp_enable_switch.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/switch/switch.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class AcompEnableSwitch : public switch_::Switch, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
AcompEnableSwitch() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void write_state(bool value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include "limiter_enable_switch.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void LimiterEnableSwitch::write_state(bool value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_limiter_enable(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/switch/limiter_enable_switch.h
Normal file
18
esphome/components/si4713_i2c/switch/limiter_enable_switch.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/switch/switch.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class LimiterEnableSwitch : public switch_::Switch, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
LimiterEnableSwitch() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void write_state(bool value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
12
esphome/components/si4713_i2c/switch/pilot_enable_switch.cpp
Normal file
12
esphome/components/si4713_i2c/switch/pilot_enable_switch.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "pilot_enable_switch.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
void PilotEnableSwitch::write_state(bool value) {
|
||||||
|
this->publish_state(value);
|
||||||
|
this->parent_->set_pilot_enable(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
18
esphome/components/si4713_i2c/switch/pilot_enable_switch.h
Normal file
18
esphome/components/si4713_i2c/switch/pilot_enable_switch.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/components/switch/switch.h"
|
||||||
|
#include "../si4713.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace si4713 {
|
||||||
|
|
||||||
|
class PilotEnableSwitch : public switch_::Switch, public Parented<Si4713Component> {
|
||||||
|
public:
|
||||||
|
PilotEnableSwitch() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void write_state(bool value) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace si4713
|
||||||
|
} // namespace esphome
|
|
@ -18,8 +18,9 @@ from .. import (
|
||||||
CONF_SI4713_ID,
|
CONF_SI4713_ID,
|
||||||
Si4713Component,
|
Si4713Component,
|
||||||
si4713_ns,
|
si4713_ns,
|
||||||
CONF_RDS_STATION,
|
CONF_SECTION_RDS,
|
||||||
CONF_RDS_TEXT,
|
CONF_STATION,
|
||||||
|
CONF_TEXT,
|
||||||
ICON_FORMAT_TEXT,
|
ICON_FORMAT_TEXT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -123,32 +124,38 @@ async def new_text(
|
||||||
CONFIG_SCHEMA = cv.Schema(
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
|
cv.GenerateID(CONF_SI4713_ID): cv.use_id(Si4713Component),
|
||||||
cv.Optional(CONF_RDS_STATION): text_schema(
|
cv.Optional(CONF_SECTION_RDS): cv.Schema(
|
||||||
|
{
|
||||||
|
cv.Optional(CONF_STATION): text_schema(
|
||||||
RDSStationText,
|
RDSStationText,
|
||||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
icon=ICON_FORMAT_TEXT,
|
icon=ICON_FORMAT_TEXT,
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_RDS_TEXT): text_schema(
|
cv.Optional(CONF_TEXT): text_schema(
|
||||||
RDSTextText,
|
RDSTextText,
|
||||||
entity_category=ENTITY_CATEGORY_CONFIG,
|
entity_category=ENTITY_CATEGORY_CONFIG,
|
||||||
icon=ICON_FORMAT_TEXT,
|
icon=ICON_FORMAT_TEXT,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
),
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def new_text_simple(config, id, setter, min_length, max_length, *args):
|
async def new_text_simple(parent, config, id, setter, min_length, max_length, *args):
|
||||||
if c := config.get(id):
|
if c := config.get(id):
|
||||||
t = await new_text(c, *args, min_length=min_length, max_length=max_length)
|
t = await new_text(c, *args, min_length=min_length, max_length=max_length)
|
||||||
await cg.register_parented(t, config[CONF_SI4713_ID])
|
await cg.register_parented(t, parent)
|
||||||
cg.add(setter(t))
|
cg.add(setter(t))
|
||||||
|
return t
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
c = await cg.get_variable(config[CONF_SI4713_ID])
|
parent = await cg.get_variable(config[CONF_SI4713_ID])
|
||||||
|
if rds_config := config.get(CONF_SECTION_RDS):
|
||||||
await new_text_simple(
|
await new_text_simple(
|
||||||
config, CONF_RDS_STATION, c.set_rds_station_text, 0, si4713_ns.RDS_STATION_MAX
|
parent, rds_config, CONF_STATION, parent.set_rds_station_text, 0, si4713_ns.RDS_STATION_MAX
|
||||||
)
|
)
|
||||||
await new_text_simple(
|
await new_text_simple(
|
||||||
config, CONF_RDS_TEXT, c.set_rds_text_text, 0, si4713_ns.RDS_TEXT_MAX
|
parent, rds_config, CONF_TEXT, parent.set_rds_text_text, 0, si4713_ns.RDS_TEXT_MAX
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue