kopia lustrzana https://github.com/OpenRTX/OpenRTX
Fix squelch behaviour on T-TWR Plus
On LILYGO T-TWR Plus the squelch was being controlled by AT1846s, resulting in the squelch bar setting being completely ignored. Now we are introducing the support for a new command of sa8x8-fw called AT+AUDIO that controls the muting or unmuting of the speaker power amplifier, enabling us to: 1. Disable AT1846s embedded squelch 2. Enable OpeRTX squelch Also fixed a bug where the sa8x8-fw version was incorrectly checked. AT+AUDIO requires sa8x8-fw version v1.3.0.r1, bumped version check in OpenRTX. TG-553pull/200/head
rodzic
744ad85799
commit
4697be5ea6
|
@ -0,0 +1,91 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2023 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include <interfaces/audio.h>
|
||||
|
||||
const struct audioDevice outputDevices[] =
|
||||
{
|
||||
{NULL, 0, 0, SINK_MCU},
|
||||
{NULL, 0, 0, SINK_RTX},
|
||||
{NULL, 0, 0, SINK_SPK},
|
||||
};
|
||||
|
||||
const struct audioDevice inputDevices[] =
|
||||
{
|
||||
{NULL, 0, 0, SINK_MCU},
|
||||
{NULL, 0, 0, SINK_RTX},
|
||||
{NULL, 0, 0, SINK_SPK},
|
||||
};
|
||||
|
||||
void audio_init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void audio_terminate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void audio_connect(const enum AudioSource source, const enum AudioSink sink)
|
||||
{
|
||||
/*
|
||||
* Squelch implementation:
|
||||
* when an audio path is created between SOURCE_RTX and SINK_SPK, unmute
|
||||
* speaker power amplifier to hear analog fm audio.
|
||||
*/
|
||||
if (source == SOURCE_RTX && sink == SINK_SPK)
|
||||
sa8x8_setAudio(true);
|
||||
}
|
||||
|
||||
void audio_disconnect(const enum AudioSource source, const enum AudioSink sink)
|
||||
{
|
||||
/*
|
||||
* Squelch implementation:
|
||||
* when an audio path is released between SOURCE_RTX and SINK_SPK, mute
|
||||
* speaker power amplifier to squelch noise.
|
||||
*/
|
||||
if (source == SOURCE_RTX && sink == SINK_SPK)
|
||||
sa8x8_setAudio(false);
|
||||
}
|
||||
|
||||
bool audio_checkPathCompatibility(const enum AudioSource p1Source,
|
||||
const enum AudioSink p1Sink,
|
||||
const enum AudioSource p2Source,
|
||||
const enum AudioSink p2Sink)
|
||||
|
||||
{
|
||||
static const uint8_t RTX_SPK = (SOURCE_RTX * 3) + SINK_SPK;
|
||||
static const uint8_t MIC_RTX = (SOURCE_MIC * 3) + SINK_RTX;
|
||||
|
||||
uint8_t p1 = (p1Source * 3) + p1Sink;
|
||||
uint8_t p2 = (p2Source * 3) + p2Sink;
|
||||
|
||||
// RTX-SPK and MIC-RTX are compatible
|
||||
if((p1 == RTX_SPK) && (p2 == MIC_RTX))
|
||||
return true;
|
||||
|
||||
// Same as above but with the paths swapped
|
||||
if((p1 == MIC_RTX) && (p2 == RTX_SPK))
|
||||
return true;
|
||||
|
||||
// Disallow all the other path combinations
|
||||
return false;
|
||||
}
|
|
@ -87,7 +87,7 @@ void AT1846S::setBandwidth(const AT1846S_BW band)
|
|||
// 25kHz bandwidth
|
||||
i2c_writeReg16(0x15, 0x1F00); // Tuning bit
|
||||
i2c_writeReg16(0x32, 0x7564); // AGC target power
|
||||
i2c_writeReg16(0x3A, 0x44C3); // Modulation detect sel
|
||||
i2c_writeReg16(0x3A, 0x4003); // Modulation detect sel
|
||||
i2c_writeReg16(0x3F, 0x29D2); // RSSI 3 threshold
|
||||
i2c_writeReg16(0x3C, 0x0E1C); // Peak detect threshold
|
||||
i2c_writeReg16(0x48, 0x1E38); // Noise 1 threshold
|
||||
|
@ -113,7 +113,7 @@ void AT1846S::setBandwidth(const AT1846S_BW band)
|
|||
// 12.5kHz bandwidth
|
||||
i2c_writeReg16(0x15, 0x1100); // Tuning bit
|
||||
i2c_writeReg16(0x32, 0x4495); // AGC target power
|
||||
i2c_writeReg16(0x3A, 0x40C3); // Modulation detect sel
|
||||
i2c_writeReg16(0x3A, 0x4003); // Modulation detect sel
|
||||
i2c_writeReg16(0x3F, 0x28D0); // RSSI 3 threshold
|
||||
i2c_writeReg16(0x3C, 0x0F1E); // Peak detect threshold
|
||||
i2c_writeReg16(0x48, 0x1DB6); // Noise 1 threshold
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
* Minimum required version of sa868-fw
|
||||
*/
|
||||
#define SA868FW_MAJOR 1
|
||||
#define SA868FW_MINOR 1
|
||||
#define SA868FW_MINOR 3
|
||||
#define SA868FW_PATCH 0
|
||||
#define SA868FW_RELEASE 20
|
||||
#define SA868FW_RELEASE 1
|
||||
|
||||
|
||||
#if DT_NODE_HAS_STATUS(DT_ALIAS(radio), okay)
|
||||
|
@ -122,8 +122,10 @@ static inline bool checkFwVersion()
|
|||
sscanf(fwVersionStr, "sa8x8-fw/v%hhu.%hhu.%hhu.r%hhu", &major, &minor,
|
||||
&patch, &release);
|
||||
|
||||
if((major >= SA868FW_MAJOR) && (minor >= SA868FW_MINOR) &&
|
||||
(patch >= SA868FW_PATCH) && (release >= SA868FW_RELEASE))
|
||||
if((major > SA868FW_MAJOR) ||
|
||||
(major == SA868FW_MAJOR) && (minor > SA868FW_MINOR) ||
|
||||
(major == SA868FW_MAJOR) && (minor == SA868FW_MINOR) && (patch > SA868FW_PATCH) ||
|
||||
(major == SA868FW_MAJOR) && (minor == SA868FW_MINOR) && (patch == SA868FW_PATCH) && (release >= SA868FW_RELEASE))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -279,7 +281,19 @@ void sa8x8_setTxPower(const float power)
|
|||
uint8_t amp_enable = (power > 1.0f) ? 1 : 0;
|
||||
int ret = gpio_pin_set_dt(&radio_pwr, amp_enable);
|
||||
if(ret != 0)
|
||||
printk("SA8x8: failed to enable high power mode");
|
||||
printk("SA8x8: failed to change power mode");
|
||||
}
|
||||
|
||||
void sa8x8_setAudio(bool value)
|
||||
{
|
||||
char buf[SA8X8_MSG_SIZE];
|
||||
|
||||
uartPrint("AT+AUDIO=%d\r\n", value);
|
||||
k_msgq_get(&uart_msgq, buf, K_MSEC(100));
|
||||
|
||||
// Check that response is "OK\r"
|
||||
if(strncmp(buf, "OK\r", 3U) != 0)
|
||||
printk("SA8x8: failed to enable control speaker power amplifier");
|
||||
}
|
||||
|
||||
void sa8x8_writeAT1846Sreg(uint8_t reg, uint16_t value)
|
||||
|
|
|
@ -62,6 +62,13 @@ int sa8x8_enableHSMode();
|
|||
*/
|
||||
void sa8x8_setTxPower(const float power);
|
||||
|
||||
/**
|
||||
* Enable or disable the speaker power amplifier.
|
||||
*
|
||||
* @param value: boolean state of the speaker power amplifier.
|
||||
*/
|
||||
void sa8x8_setAudio(bool value);
|
||||
|
||||
/**
|
||||
* Write a register of the AT1846S radio IC contained in the SA8x8 module.
|
||||
*
|
||||
|
|
|
@ -43,6 +43,9 @@ void radio_init(const rtxStatus_t *rtxState)
|
|||
// platform_init()
|
||||
sa8x8_enableHSMode();
|
||||
|
||||
// Mute speaker power amplifier by default
|
||||
sa8x8_setAudio(false);
|
||||
|
||||
/*
|
||||
* Configure AT1846S, keep AF output disabled at power on.
|
||||
*/
|
||||
|
|
|
@ -18,8 +18,8 @@ target_sources(app
|
|||
${OPENRTX_ROOT}/platform/drivers/baseband/AT1846S_SA8x8.cpp
|
||||
${OPENRTX_ROOT}/platform/drivers/baseband/SA8x8.c
|
||||
${OPENRTX_ROOT}/platform/drivers/GPS/GPS_ttwrplus.c
|
||||
${OPENRTX_ROOT}/platform/drivers/audio/audio_ttwrplus.c
|
||||
|
||||
${OPENRTX_ROOT}/platform/drivers/stubs/audio_stub.c
|
||||
${OPENRTX_ROOT}/platform/drivers/stubs/cps_io_stub.c
|
||||
${OPENRTX_ROOT}/platform/drivers/stubs/nvmem_stub.c
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue