diff --git a/openrtx/src/rtx/OpMode_FM.cpp b/openrtx/src/rtx/OpMode_FM.cpp index b5d0fdd7..7612093f 100644 --- a/openrtx/src/rtx/OpMode_FM.cpp +++ b/openrtx/src/rtx/OpMode_FM.cpp @@ -39,16 +39,17 @@ #ifdef PLATFORM_MDUV3x0 void _setVolume() { - // Volume level range is 0 - 255, by right shifting by 3 we get a value in - // range 0 - 31. + static uint8_t oldVolume = 0xFF; uint8_t volume = platform_getVolumeLevel(); - volume >>= 3; - if(volume >= 1) - { - // Setting HR_C6000 volume to 0 = max volume - HR_C6000::instance().setDacGain(volume); - } + if(volume == oldVolume) + return; + + // Apply new volume level, map 0 - 255 range into -31 to 31 + int8_t gain = ((int8_t) (volume / 4)) - 31; + HR_C6000::instance().setDacGain(gain); + + oldVolume = volume; } #endif @@ -85,6 +86,11 @@ void OpMode_FM::update(rtxStatus_t *const status, const bool newCfg) { (void) newCfg; + #ifdef PLATFORM_MDUV3x0 + // Set output volume by changing the HR_C6000 DAC gain + _setVolume(); + #endif + // RX logic if(status->opStatus == RX) { @@ -114,12 +120,6 @@ void OpMode_FM::update(rtxStatus_t *const status, const bool newCfg) audioPath_release(rxAudioPath); sqlOpen = false; } - - #ifdef PLATFORM_MDUV3x0 - // Set output volume by changing the HR_C6000 DAC gain - if(sqlOpen == true) _setVolume(); - #endif - } else if((status->opStatus == OFF) && enterRx) { diff --git a/platform/drivers/baseband/HR_C6000_UV3x0.cpp b/platform/drivers/baseband/HR_C6000_UV3x0.cpp index 8eff8ff3..f7266301 100644 --- a/platform/drivers/baseband/HR_C6000_UV3x0.cpp +++ b/platform/drivers/baseband/HR_C6000_UV3x0.cpp @@ -102,7 +102,7 @@ void HR_Cx000< M >::init() writeReg(M::CONFIG, 0x65, 0x0A); // Undocumented register writeReg(M::CONFIG, 0x1D, 0xFF); // Local unaddress, mask unaddress (?) writeReg(M::CONFIG, 0x1E, 0xF1); // Broadcast RX address, broadcast address mask - writeReg(M::CONFIG, 0xE2, 0x06); // Mic preamp disabled, anti-pop enabled + writeReg(M::CONFIG, 0xE2, 0x00); // DAC off, mic preamp disabled writeReg(M::CONFIG, 0xE4, 0x27); // Lineout gain, first and second stage mic gain writeReg(M::CONFIG, 0xE3, 0x52); // Internal ADC and DAC passthrough enable writeReg(M::CONFIG, 0xE5, 0x1A); // Undocumented register @@ -172,7 +172,6 @@ void HR_Cx000< M >::fmMode() writeReg(M::CONFIG, 0x81, 0x04); // Interrupt mask writeReg(M::CONFIG, 0xE5, 0x1A); // Undocumented register writeReg(M::CONFIG, 0xE4, 0x27); // Lineout gain, first and second stage mic gain - writeReg(M::CONFIG, 0xE2, 0x06); // Mic preamp disabled, anti-pop enabled writeReg(M::CONFIG, 0x34, 0x98); // FM bpf enabled, 25kHz bandwidth writeReg(M::CONFIG, 0x60, 0x00); // Disable both analog and DMR transmission writeReg(M::CONFIG, 0x1F, 0x00); // Color code, encryption disabled @@ -187,8 +186,6 @@ void HR_Cx000< M >::fmMode() sendSequence(initSeq7, sizeof(initSeq7)); writeReg(M::CONFIG, 0x11, 0x80); // Local channel mode writeReg(M::CONFIG, 0xE0, 0xC9); // Codec enabled, LineIn1, LineOut2, I2S slave mode - - writeReg(M::CONFIG, 0x37, 0x81); // DAC gain } template< class M > @@ -218,7 +215,6 @@ void HR_Cx000< M >::startAnalogTx(const TxAudioSource source, const FmConfig cfg writeReg(M::AUX, 0x50, 0x00); writeReg(M::AUX, 0x51, 0x00); writeReg(M::CONFIG, 0x3E, 0x08); // FM Modulation frequency deviation coefficient at the receiving end - writeReg(M::CONFIG, 0x37, 0x8C); // DAC gain writeReg(M::CONFIG, 0x60, 0x80); // Start analog transmission } @@ -227,9 +223,7 @@ void HR_Cx000< M >::stopAnalogTx() { writeReg(M::CONFIG, 0x60, 0x00); // Stop analog transmission writeReg(M::CONFIG, 0xE0, 0xC9); // Codec enabled, LineIn1, LineOut2, I2S slave mode - writeReg(M::CONFIG, 0xE2, 0x06); // Mic preamp disabled, anti-pop enabled writeReg(M::CONFIG, 0x34, 0x98); // FM bpf enabled, 25kHz bandwidth - writeReg(M::CONFIG, 0x37, 0x81); // DAC gain writeReg(M::CONFIG, 0x26, 0xFD); // Undocumented register, enable FM receive } diff --git a/platform/drivers/baseband/HR_Cx000.cpp b/platform/drivers/baseband/HR_Cx000.cpp index 32c1c54a..edf4d9cb 100644 --- a/platform/drivers/baseband/HR_Cx000.cpp +++ b/platform/drivers/baseband/HR_Cx000.cpp @@ -32,18 +32,28 @@ bool Cx000_uSpiBusy() } template <> -void HR_Cx000< C5000_SpiOpModes >::setDacGain(uint8_t value) +void HR_Cx000< C5000_SpiOpModes >::setDacGain(int8_t gain) { // TODO: "DALin" register for HR_C5000 is not documented. - (void) value; + (void) gain; } template <> -void HR_Cx000< C6000_SpiOpModes >::setDacGain(uint8_t value) +void HR_Cx000< C6000_SpiOpModes >::setDacGain(int8_t gain) { - if(value < 1) value = 1; - if(value > 31) value = 31; - writeReg(C6000_SpiOpModes::CONFIG, 0x37, (0x80 | value)); + // If gain is at minimum, just turn off DAC output and return + if(gain <= -31) + { + writeReg(C6000_SpiOpModes::CONFIG, 0xE2, 0x00); + return; + } + + uint8_t value = 0x80 | (((uint8_t) gain) & 0x1F); + if(gain > 0) + value |= 0x40; + + writeReg(C6000_SpiOpModes::CONFIG, 0x37, value); // DAC gain + writeReg(C6000_SpiOpModes::CONFIG, 0xE2, 0x02); // Enable DAC } template <> diff --git a/platform/drivers/baseband/HR_Cx000.h b/platform/drivers/baseband/HR_Cx000.h index 02b5d3e7..d076c39d 100644 --- a/platform/drivers/baseband/HR_Cx000.h +++ b/platform/drivers/baseband/HR_Cx000.h @@ -146,12 +146,12 @@ public: } /** - * Set the gain of the audio DAC stage. This value affects the sound volume - * in RX mode. + * Set the gain of the audio DAC stage, each step corresponds to an 1.5dB + * variation. * - * @param value: gain value. Allowed range is 1-31. + * @param gain: gain value. Allowed range is from -31 to +31. */ - void setDacGain(uint8_t value); + void setDacGain(int8_t gain); /** * Set the gain for the incoming audio from both the microphone and line-in