diff --git a/firmware/application/audio.cpp b/firmware/application/audio.cpp index 0bbe8cbf8..f252c891e 100644 --- a/firmware/application/audio.cpp +++ b/firmware/application/audio.cpp @@ -225,8 +225,15 @@ volume_range_t volume_range() { return audio_codec->headphone_gain_range(); } -void set_volume(const volume_t volume) { - audio_codec->set_headphone_volume(volume); +bool set_volume(const volume_t volume) { + // add retry method + for (int i = 0; i < 100; ++i) { + if (audio_codec->set_headphone_volume(volume)) { + return true; + } + chThdSleepMilliseconds(2); + } + return false; } } /* namespace headphone */ diff --git a/firmware/application/audio.hpp b/firmware/application/audio.hpp index 06e00c253..2999b0401 100644 --- a/firmware/application/audio.hpp +++ b/firmware/application/audio.hpp @@ -49,7 +49,7 @@ class Codec { virtual void headphone_enable() = 0; virtual void headphone_disable() = 0; virtual volume_range_t headphone_gain_range() const = 0; - virtual void set_headphone_volume(const volume_t volume) = 0; + virtual bool set_headphone_volume(const volume_t volume) = 0; virtual void microphone_enable(int8_t alc_mode, bool mic_to_HP_enabled) = 0; // added user-GUI AK4951 ,selected ALC mode. virtual void microphone_disable() = 0; @@ -93,7 +93,7 @@ namespace headphone { volume_range_t volume_range(); -void set_volume(const volume_t volume); +bool set_volume(const volume_t volume); } /* namespace headphone */ diff --git a/firmware/common/ak4951.cpp b/firmware/common/ak4951.cpp index 8106e27be..bf67a4283 100644 --- a/firmware/common/ak4951.cpp +++ b/firmware/common/ak4951.cpp @@ -130,15 +130,15 @@ bool AK4951::reset() { return true; } -void AK4951::set_digtal_volume_control(const reg_t value) { +bool AK4951::set_digtal_volume_control(const reg_t value) { map.r.l_ch_digital_volume_control.DV = value; - update(Register::LchDigitalVolumeControl); + return update(Register::LchDigitalVolumeControl); } -void AK4951::set_headphone_volume(const volume_t volume) { +bool AK4951::set_headphone_volume(const volume_t volume) { const auto normalized = headphone_gain_range().normalize(volume); auto n = normalized.centibel() / 5; - set_digtal_volume_control(0xcb - n); + return set_digtal_volume_control(0xcb - n); } void AK4951::headphone_mute() { @@ -602,13 +602,13 @@ reg_t AK4951::read(const address_t reg_address) { return rx[0]; } -void AK4951::update(const Register reg) { - write(toUType(reg), map.w[toUType(reg)]); +bool AK4951::update(const Register reg) { + return write(toUType(reg), map.w[toUType(reg)]); } -void AK4951::write(const address_t reg_address, const reg_t value) { +bool AK4951::write(const address_t reg_address, const reg_t value) { const std::array tx{reg_address, value}; - bus.transmit(bus_address, tx.data(), tx.size()); + return bus.transmit(bus_address, tx.data(), tx.size()); } } /* namespace ak4951 */ diff --git a/firmware/common/ak4951.hpp b/firmware/common/ak4951.hpp index b591b6210..dc98da520 100644 --- a/firmware/common/ak4951.hpp +++ b/firmware/common/ak4951.hpp @@ -841,7 +841,7 @@ class AK4951 : public audio::Codec { return true; } - void set_headphone_volume(const volume_t volume) override; + bool set_headphone_volume(const volume_t volume) override; void headphone_mute(); void microphone_enable(int8_t alc_mode, bool mic_to_HP_enabled); // added user GUI parameter , to set up AK4951 ALC mode, and mic_to_HP_enabled to control "Hear to Mic" @@ -879,15 +879,15 @@ class AK4951 : public audio::Codec { void configure_digital_interface_i2s(); void configure_digital_interface_external_slave(); void configure_digital_interface_external_master(); - void set_digtal_volume_control(const reg_t value); + bool set_digtal_volume_control(const reg_t value); void set_dac_power(const bool enable); void set_headphone_power(const bool enable); void set_speaker_power(const bool enable); void select_line_out(const LineOutSelect value); reg_t read(const address_t reg_address); - void update(const Register reg); - void write(const address_t reg_address, const reg_t value); + bool update(const Register reg); + bool write(const address_t reg_address, const reg_t value); }; } /* namespace ak4951 */ diff --git a/firmware/common/wm8731.cpp b/firmware/common/wm8731.cpp index 111b9985e..415d821a5 100644 --- a/firmware/common/wm8731.cpp +++ b/firmware/common/wm8731.cpp @@ -145,14 +145,14 @@ void WM8731::write(const RightLineIn value) { write(Register::RightLineIn); } -void WM8731::write(const LeftHeadphoneOut value) { +bool WM8731::write(const LeftHeadphoneOut value) { map.r.left_headphone_out = value; - write(Register::LeftHeadphoneOut); + return write(Register::LeftHeadphoneOut); } -void WM8731::write(const RightHeadphoneOut value) { +bool WM8731::write(const RightHeadphoneOut value) { map.r.right_headphone_out = value; - write(Register::RightHeadphoneOut); + return write(Register::RightHeadphoneOut); } void WM8731::write(const AnalogAudioPathControl value) { diff --git a/firmware/common/wm8731.hpp b/firmware/common/wm8731.hpp index ad353f589..d5a83e63d 100644 --- a/firmware/common/wm8731.hpp +++ b/firmware/common/wm8731.hpp @@ -306,21 +306,22 @@ class WM8731 : public audio::Codec { }); } - void set_wm_headphone_volume(const volume_t volume) { + bool set_wm_headphone_volume(const volume_t volume) { const auto normalized = headphone_gain_range().normalize(volume); auto n = normalized.centibel() / 10; - write(LeftHeadphoneOut{ + bool tag = write(LeftHeadphoneOut{ .lhpvol = static_cast(n), .lzcen = 0, .lrhpboth = 1, .reserved0 = 0, }); + return tag; } - void set_headphone_volume(const volume_t volume) override { + bool set_headphone_volume(const volume_t volume) override { headphone_volume = volume; - set_wm_headphone_volume(volume); + return set_wm_headphone_volume(volume); } volume_range_t headphone_gain_range() const override { @@ -422,8 +423,8 @@ class WM8731 : public audio::Codec { void write(const LeftLineIn value); void write(const RightLineIn value); - void write(const LeftHeadphoneOut value); - void write(const RightHeadphoneOut value); + bool write(const LeftHeadphoneOut value); + bool write(const RightHeadphoneOut value); void write(const AnalogAudioPathControl value); void write(const DigitalAudioPathControl value); void write(const PowerDownControl value);