From 5288441a820d62a50bf4cd7da0b4dc1e43fde1d5 Mon Sep 17 00:00:00 2001 From: richardclli Date: Thu, 15 Jun 2023 08:07:30 +0800 Subject: [PATCH] fix(el18): Audio output should be OFF if no audio playing (#3670) * Added audio on/off depends whether audio content is present. * Aligned the mute control with the implementation in the DAC driver. * Mute Pin should be inverted. * Removed PCB specific dependencies. * chore: Formatting and cleanup --- radio/src/audio.cpp | 2 - radio/src/targets/nv14/audio_spi_driver.cpp | 83 +++++++++++++++++---- radio/src/targets/nv14/board.cpp | 10 --- radio/src/targets/nv14/hal.h | 7 +- 4 files changed, 74 insertions(+), 28 deletions(-) diff --git a/radio/src/audio.cpp b/radio/src/audio.cpp index a4555178d..07ddc1725 100644 --- a/radio/src/audio.cpp +++ b/radio/src/audio.cpp @@ -525,8 +525,6 @@ void audioTask(void * pdata) #if defined(PCBX12S) || defined(RADIO_TX16S) // The audio amp needs ~2s to start RTOS_WAIT_MS(1000); // 1s -#elif defined(PCBNV14) - audioOn(); #endif while (true) { diff --git a/radio/src/targets/nv14/audio_spi_driver.cpp b/radio/src/targets/nv14/audio_spi_driver.cpp index 8563c0773..965544946 100644 --- a/radio/src/targets/nv14/audio_spi_driver.cpp +++ b/radio/src/targets/nv14/audio_spi_driver.cpp @@ -357,36 +357,83 @@ void audioSendRiffHeader() audioSpiWriteBuffer(RiffHeader, sizeof(RiffHeader)); } -#if defined(PCBX12S) || defined(PCBNV14) - -void audioOn() +#if defined(AUDIO_MUTE_GPIO_PIN) +static inline void setMutePin(bool enabled) { - GPIO_SetBits(AUDIO_SHUTDOWN_GPIO, AUDIO_SHUTDOWN_GPIO_PIN); + if (enabled) { +#if defined(INVERTED_MUTE_PIN) + GPIO_ResetBits(AUDIO_MUTE_GPIO, AUDIO_MUTE_GPIO_PIN); +#else + GPIO_SetBits(AUDIO_MUTE_GPIO, AUDIO_MUTE_GPIO_PIN); +#endif + } else { +#if defined(INVERTED_MUTE_PIN) + GPIO_SetBits(AUDIO_MUTE_GPIO, AUDIO_MUTE_GPIO_PIN); +#else + GPIO_ResetBits(AUDIO_MUTE_GPIO, AUDIO_MUTE_GPIO_PIN); +#endif + } } -void audioOff() +static inline bool getMutePin(void) { - GPIO_ResetBits(AUDIO_SHUTDOWN_GPIO, AUDIO_SHUTDOWN_GPIO_PIN); +#if defined(INVERTED_MUTE_PIN) + return !GPIO_ReadOutputDataBit(AUDIO_MUTE_GPIO, AUDIO_MUTE_GPIO_PIN); +#else + return GPIO_ReadOutputDataBit(AUDIO_MUTE_GPIO, AUDIO_MUTE_GPIO_PIN); +#endif } -void audioShutdownInit() +void audioMute() +{ +#if defined(AUDIO_UNMUTE_DELAY) + tmr10ms_t now = get_tmr10ms(); + if (!audioQueue.lastAudioPlayTime) { + // we start the mute delay now + audioQueue.lastAudioPlayTime = now; + } else if (now - audioQueue.lastAudioPlayTime > AUDIO_MUTE_DELAY / 10) { + // delay expired, we may mute + setMutePin(true); + } +#else + // mute + setMutePin(true); +#endif +} + +void audioUnmute() +{ +#if defined(AUDIO_UNMUTE_DELAY) + // if muted + if (getMutePin()) { + // ..un-mute + setMutePin(false); + RTOS_WAIT_MS(AUDIO_UNMUTE_DELAY); + } + // reset the mute delay + audioQueue.lastAudioPlayTime = 0; +#else + setMutePin(false); +#endif +} + +void audioMuteInit() { GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = AUDIO_SHUTDOWN_GPIO_PIN; + GPIO_InitStructure.GPIO_Pin = AUDIO_MUTE_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(AUDIO_SHUTDOWN_GPIO, &GPIO_InitStructure); - GPIO_ResetBits(AUDIO_SHUTDOWN_GPIO, AUDIO_SHUTDOWN_GPIO_PIN); + GPIO_Init(AUDIO_MUTE_GPIO, &GPIO_InitStructure); + GPIO_ResetBits(AUDIO_MUTE_GPIO, AUDIO_MUTE_GPIO_PIN); } #endif void audioInit() { -#if defined(PCBX12S) || defined(PCBNV14) - audioShutdownInit(); - // TODO X10 code missing +#if defined(AUDIO_MUTE_GPIO_PIN) + audioMuteInit(); #endif audioSpiInit(); @@ -427,6 +474,9 @@ void audioConsumeCurrentBuffer() } if (currentBuffer) { +#if defined(AUDIO_MUTE_GPIO_PIN) + audioUnmute(); +#endif uint32_t written = audioSpiWriteData(currentBuffer, currentSize); currentBuffer += written; currentSize -= written; @@ -436,6 +486,11 @@ void audioConsumeCurrentBuffer() currentSize = 0; } } +#if defined(AUDIO_MUTE_GPIO_PIN) + else { + audioMute(); + } +#endif } // adjust this value for a volume level just above the silence @@ -450,7 +505,7 @@ void setScaledVolume(uint8_t volume) } // maximum volume is 0x00 and total silence is 0xFE if (volume == 0) { - setVolume(0xFE); // silence + setVolume(0xFE); // silence } else { uint32_t vol = (VOLUME_MIN_DB * 2) - ((uint32_t)volume * (VOLUME_MIN_DB * 2)) / VOLUME_LEVEL_MAX; diff --git a/radio/src/targets/nv14/board.cpp b/radio/src/targets/nv14/board.cpp index 3cf36007e..f2b96c622 100644 --- a/radio/src/targets/nv14/board.cpp +++ b/radio/src/targets/nv14/board.cpp @@ -262,16 +262,6 @@ void boardOff() SysTick->CTRL = 0; // turn off systick - // Shutdown the Audio amp - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.GPIO_Pin = AUDIO_SHUTDOWN_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(AUDIO_SHUTDOWN_GPIO, &GPIO_InitStructure); - GPIO_ResetBits(AUDIO_SHUTDOWN_GPIO, AUDIO_SHUTDOWN_GPIO_PIN); - // Shutdown the Haptic hapticDone(); diff --git a/radio/src/targets/nv14/hal.h b/radio/src/targets/nv14/hal.h index db73de640..68263be79 100644 --- a/radio/src/targets/nv14/hal.h +++ b/radio/src/targets/nv14/hal.h @@ -322,8 +322,6 @@ // Audio #define AUDIO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOH) #define AUDIO_RCC_APB2Periph RCC_APB2Periph_SPI1 -#define AUDIO_SHUTDOWN_GPIO GPIOH -#define AUDIO_SHUTDOWN_GPIO_PIN GPIO_Pin_8 // PH.08 audio amp control pin #define AUDIO_XDCS_GPIO GPIOH #define AUDIO_XDCS_GPIO_PIN GPIO_Pin_14 // PH.14 #define AUDIO_CS_GPIO GPIOH @@ -343,6 +341,11 @@ #define AUDIO_SPI_MOSI_GPIO GPIOB #define AUDIO_SPI_MOSI_GPIO_PIN GPIO_Pin_5 // PB.05 #define AUDIO_SPI_MOSI_GPIO_PinSource GPIO_PinSource5 +#define AUDIO_MUTE_GPIO GPIOH +#define AUDIO_MUTE_GPIO_PIN GPIO_Pin_8 // PH.08 audio amp control pin +#define AUDIO_UNMUTE_DELAY 120 // ms +#define AUDIO_MUTE_DELAY 500 // ms +#define INVERTED_MUTE_PIN // I2C Bus #define I2C_B1 I2C1