From f4ecf03a9e8eb67eea523ce7fb4eab8a81fc5317 Mon Sep 17 00:00:00 2001 From: 3djc Date: Sat, 18 Oct 2025 12:39:13 +0200 Subject: [PATCH] fix(tx15): headphone detection (#6686) --- radio/src/boards/rm-h750/audio_driver.cpp | 7 ++++++- radio/src/drivers/tas2505.cpp | 11 ++++++++--- radio/src/drivers/tas2505.h | 2 +- radio/src/hal/audio_driver.h | 2 +- radio/src/main.cpp | 10 ++++++++++ radio/src/targets/simu/audio_driver.cpp | 7 +++++++ 6 files changed, 33 insertions(+), 6 deletions(-) diff --git a/radio/src/boards/rm-h750/audio_driver.cpp b/radio/src/boards/rm-h750/audio_driver.cpp index 77c636a98..abbd5b4a2 100644 --- a/radio/src/boards/rm-h750/audio_driver.cpp +++ b/radio/src/boards/rm-h750/audio_driver.cpp @@ -139,9 +139,14 @@ static void audio_update_dma_buffer(uint8_t tc) } } +bool audioHeadphoneDetect() +{ + return gpio_read(AUDIO_HP_DETECT_PIN); +} + void audioSetVolume(uint8_t volume) { - tas2505_set_volume(&_tas2505, volume * 9 / 10); // TX15 HP cannot handle the full power of TAS2505 + tas2505_set_volume(&_tas2505, volume * 9 / 10, audioHeadphoneDetect()); // TX15 HP cannot handle the full power of TAS2505 } extern "C" void DMA1_Stream4_IRQHandler(void) diff --git a/radio/src/drivers/tas2505.cpp b/radio/src/drivers/tas2505.cpp index a9187ccc5..e701ed3a3 100644 --- a/radio/src/drivers/tas2505.cpp +++ b/radio/src/drivers/tas2505.cpp @@ -133,7 +133,7 @@ int tas2505_init(tas2505_t* dev) // max value is 126 #define VOLUME_MIN_DB 60 -void tas2505_set_volume(tas2505_t* dev, uint8_t volume) +void tas2505_set_volume(tas2505_t* dev, uint8_t volume, bool headphone_mode = false) { if (volume > VOLUME_LEVEL_MAX) { volume = VOLUME_LEVEL_MAX; @@ -145,7 +145,12 @@ void tas2505_set_volume(tas2505_t* dev, uint8_t volume) } else { uint32_t vol = (VOLUME_MIN_DB * 2) - ((uint32_t)volume * (VOLUME_MIN_DB * 2)) / VOLUME_LEVEL_MAX; - tas2505_write_reg(dev, TAS2505_SPKVOL1, vol); - tas2505_write_reg(dev, TAS2505_HP_VOL, vol); + if (headphone_mode) { + tas2505_write_reg(dev, TAS2505_SPKVOL1, 0xFE); + tas2505_write_reg(dev, TAS2505_HP_VOL, vol); + } else { + tas2505_write_reg(dev, TAS2505_SPKVOL1, vol); + tas2505_write_reg(dev, TAS2505_HP_VOL, 0xFE); + } } } diff --git a/radio/src/drivers/tas2505.h b/radio/src/drivers/tas2505.h index 85b3e4712..3658a400c 100644 --- a/radio/src/drivers/tas2505.h +++ b/radio/src/drivers/tas2505.h @@ -94,4 +94,4 @@ typedef struct { int tas2505_probe(tas2505_t* dev, etx_i2c_bus_t bus, uint16_t addr); int tas2505_init(tas2505_t* dev); -void tas2505_set_volume(tas2505_t* dev, uint8_t volume); +void tas2505_set_volume(tas2505_t* dev, uint8_t volume, bool headphone_mode); diff --git a/radio/src/hal/audio_driver.h b/radio/src/hal/audio_driver.h index 4b4150a29..a9db8b182 100644 --- a/radio/src/hal/audio_driver.h +++ b/radio/src/hal/audio_driver.h @@ -32,7 +32,7 @@ #define AUDIO_SAMPLE_FMT_S16 0 #define AUDIO_SAMPLE_FMT_U16 1 - +bool audioHeadphoneDetect(); void audioSetVolume(uint8_t volume); void audioConsumeCurrentBuffer(); diff --git a/radio/src/main.cpp b/radio/src/main.cpp index baf2cd8f6..4cff03ab3 100644 --- a/radio/src/main.cpp +++ b/radio/src/main.cpp @@ -47,6 +47,9 @@ #if defined(AUDIO) uint8_t currentSpeakerVolume = 255; uint8_t requiredSpeakerVolume = 255; +#if defined(AUDIO_HP_DETECT_PIN) +bool hpDetected = false; +#endif #endif uint8_t currentBacklightBright = 0; @@ -207,6 +210,13 @@ void handleUsbConnection() void checkSpeakerVolume() { +#if defined(AUDIO_HP_DETECT_PIN) + // volume needs to be set on plug/unplug to set the the right volume on each device + if (hpDetected != audioHeadphoneDetect()) { + hpDetected = !hpDetected; + audioSetVolume(currentSpeakerVolume); + } +#endif #if defined(AUDIO) if (currentSpeakerVolume != requiredSpeakerVolume) { currentSpeakerVolume = requiredSpeakerVolume; diff --git a/radio/src/targets/simu/audio_driver.cpp b/radio/src/targets/simu/audio_driver.cpp index 05e5be2fe..a8f8a5616 100644 --- a/radio/src/targets/simu/audio_driver.cpp +++ b/radio/src/targets/simu/audio_driver.cpp @@ -22,6 +22,13 @@ #include "audio.h" #include "simuaudio.h" +#if defined(AUDIO_HP_DETECT_PIN) +bool audioHeadphoneDetect() +{ + return false; +} +#endif + #if !defined(SOFTWARE_VOLUME) static int _simu_volume = 0;