14constexpr uint8_t KATANA_CHIP_ID = 0x30;
16constexpr uint8_t KATANA_REG_CHIP_ID = 0x00;
17constexpr uint8_t KATANA_REG_RESET = 0x01;
18constexpr uint8_t KATANA_REG_VOLUME_1 = 0x02;
19constexpr uint8_t KATANA_REG_VOLUME_2 = 0x03;
20constexpr uint8_t KATANA_REG_MUTE = 0x04;
21constexpr uint8_t KATANA_REG_DSP_PROGRAM = 0x05;
22constexpr uint8_t KATANA_REG_DEEMPHASIS = 0x06;
23constexpr uint8_t KATANA_REG_DOP = 0x07;
24constexpr uint8_t KATANA_REG_FORMAT = 0x08;
25constexpr uint8_t KATANA_REG_COMMAND = 0x09;
26constexpr uint8_t KATANA_REG_MUTE_STREAM = 0x0A;
28constexpr float KATANA_VOLUME_MIDPOINT = 0.5f;
29constexpr float KATANA_VOLUME_MIDPOINT_STEPS = 50.0f;
31constexpr float KATANA_VOLUME_CUBIC_SCALE = 120.0f;
32constexpr uint8_t KATANA_VOLUME_FULL_ATTENUATION = 255;
35constexpr uint32_t RESET_SETTLE_DELAY_MS = 10;
37const LogString *filter_shape_to_str(
FilterShape shape) {
40 return LOG_STR(
"linear_phase_fast");
42 return LOG_STR(
"linear_phase_slow");
44 return LOG_STR(
"minimum_phase_fast");
46 return LOG_STR(
"minimum_phase_slow");
48 return LOG_STR(
"apodizing");
50 return LOG_STR(
"hybrid");
52 return LOG_STR(
"brick_wall");
59 return LOG_STR(
"32khz");
61 return LOG_STR(
"44_1khz");
63 return LOG_STR(
"48khz");
65 return LOG_STR(
"bypass");
73 if (!this->
read_byte(KATANA_REG_CHIP_ID, &chip_id)) {
77 if (chip_id != KATANA_CHIP_ID) {
78 ESP_LOGE(TAG,
"Unexpected chip ID 0x%02X", chip_id);
82 if (!this->
write_byte(KATANA_REG_RESET, 0x01)) {
86 delay(RESET_SETTLE_DELAY_MS);
95 this->
mark_failed(LOG_STR(
"Failed to configure the control logic"));
101 "ES9038Q2M Katana:\n"
102 " Filter shape: %s\n"
104 " Format register: 0x%02X\n"
108 LOG_I2C_DEVICE(
this);
111#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
112 for (uint8_t
reg = KATANA_REG_CHIP_ID;
reg <= KATANA_REG_MUTE_STREAM;
reg++) {
115 ESP_LOGV(TAG,
" Register 0x%02X: 0x%02X",
reg, value);
117 ESP_LOGV(TAG,
" Register 0x%02X: read failed",
reg);
142 volume = clamp(
volume, 0.0f, 1.0f);
144 float attenuation = KATANA_VOLUME_FULL_ATTENUATION;
145 if (
volume >= KATANA_VOLUME_MIDPOINT) {
146 attenuation = KATANA_VOLUME_MIDPOINT_STEPS * (1.0f -
volume) / (1.0f - KATANA_VOLUME_MIDPOINT);
147 }
else if (
volume > 0.0f) {
148 attenuation = KATANA_VOLUME_MIDPOINT_STEPS - KATANA_VOLUME_CUBIC_SCALE * log10f(
volume / KATANA_VOLUME_MIDPOINT);
151 static_cast<uint8_t
>(lroundf(clamp(attenuation, 0.0f,
static_cast<float>(KATANA_VOLUME_FULL_ATTENUATION))));
159 if (this->
volume_reg_ == KATANA_VOLUME_FULL_ATTENUATION)
161 if (this->
volume_reg_ <= KATANA_VOLUME_MIDPOINT_STEPS)
162 return 1.0f - this->
volume_reg_ * (1.0f - KATANA_VOLUME_MIDPOINT) / KATANA_VOLUME_MIDPOINT_STEPS;
163 return KATANA_VOLUME_MIDPOINT *
164 powf(10.0f, (KATANA_VOLUME_MIDPOINT_STEPS - this->
volume_reg_) / KATANA_VOLUME_CUBIC_SCALE);