Add Rx audio profiles for AM

This commit is contained in:
Armel FAUVEAU committed 2026-03-31 18:13:17 +02:00
1 parent 397ef318f8
commit 3d739c642e
9 files changed
+173 -54

No files matched your search

+6 -2
View File
@@ -572,7 +572,11 @@ void ACTION_MainOnly(void)
#ifdef ENABLE_FEAT_F4HWN_AUDIO
void ACTION_RxA(void)
{
gSetting_set_audio = (gSetting_set_audio + 1) % 5;
if(gRxVfo->Modulation == MODULATION_AM)
gSetting_set_audio_am = (gSetting_set_audio_am + 1) % 3;
else if (gRxVfo->Modulation == MODULATION_FM)
gSetting_set_audio_fm = (gSetting_set_audio_fm + 1) % 5;
RADIO_SetModulation(gRxVfo->Modulation);
}
#endif
@@ -678,4 +682,4 @@ void ACTION_Remove_Offset(void)
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
}
#endif
#endif
#endif
+18 -4
View File
@@ -429,7 +429,12 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
#ifdef ENABLE_FEAT_F4HWN_AUDIO
case MENU_SET_AUD:
//*pMin = 0;
*pMax = ARRAY_SIZE(gSubMenu_SET_AUD) - 1;
if(gTxVfo->Modulation == MODULATION_AM)
*pMax = ARRAY_SIZE(gSubMenu_SET_AUD_AM) - 1;
else if (gTxVfo->Modulation == MODULATION_USB)
*pMax = 0;
else
*pMax = ARRAY_SIZE(gSubMenu_SET_AUD_FM) - 1;
break;
#endif
#ifdef ENABLE_FEAT_F4HWN_NARROWER
@@ -964,8 +969,12 @@ void MENU_AcceptSetting(void)
break;
#ifdef ENABLE_FEAT_F4HWN_AUDIO
case MENU_SET_AUD:
gSetting_set_audio = gSubMenuSelection;
RADIO_SetModulation(gRxVfo->Modulation);
if(gTxVfo->Modulation == MODULATION_AM)
gSetting_set_audio_am = gSubMenuSelection;
else if (gTxVfo->Modulation == MODULATION_FM)
gSetting_set_audio_fm = gSubMenuSelection;
RADIO_SetModulation(gTxVfo->Modulation);
break;
#endif
#ifdef ENABLE_FEAT_F4HWN_NARROWER
@@ -1419,7 +1428,12 @@ void MENU_ShowCurrentSetting(void)
break;
#ifdef ENABLE_FEAT_F4HWN_AUDIO
case MENU_SET_AUD:
gSubMenuSelection = gSetting_set_audio;
if(gTxVfo->Modulation == MODULATION_AM)
gSubMenuSelection = gSetting_set_audio_am;
else if (gTxVfo->Modulation == MODULATION_USB)
gSubMenuSelection = 0;
else
gSubMenuSelection = gSetting_set_audio_fm;
break;
#endif
#ifdef ENABLE_FEAT_F4HWN_NARROWER
+2 -1
View File
@@ -127,7 +127,8 @@ enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
bool gSetting_set_met = 0;
bool gSetting_set_gui = 0;
#ifdef ENABLE_FEAT_F4HWN_AUDIO
uint8_t gSetting_set_audio = 0;
uint8_t gSetting_set_audio_fm = 0;
uint8_t gSetting_set_audio_am = 0;
#endif
#ifdef ENABLE_FEAT_F4HWN_NARROWER
bool gSetting_set_nfm = 0;
+2 -1
View File
@@ -189,7 +189,8 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
extern bool gSetting_set_met;
extern bool gSetting_set_gui;
#ifdef ENABLE_FEAT_F4HWN_AUDIO
extern uint8_t gSetting_set_audio;
extern uint8_t gSetting_set_audio_fm;
extern uint8_t gSetting_set_audio_am;
#endif
#ifdef ENABLE_FEAT_F4HWN_NARROWER
extern bool gSetting_set_nfm;
+105 -34
View File
@@ -54,7 +54,22 @@ const char gModulationStr[MODULATION_UKNOWN][4] = {
};
#ifdef ENABLE_FEAT_F4HWN_AUDIO
static void AUDIO_ApplyProfile(uint8_t profile)
// About BK4819_WriteRegister(0x2b, val) experimentation...
//
// 0x000: 300 Hz high-pass filter enabled, 3 kHz low-pass filter enabled, de-emphasis enabled.
// Audio impression: the most "classic radio" tuning, more filtered and smoother.
//
// 0x300: 300 Hz high-pass filter enabled, 3 kHz low-pass filter disabled, de-emphasis disabled.
// Audio impression: clearer, brighter, and more open, while still cutting low frequencies.
//
// 0x400: 300 Hz high-pass filter disabled, 3 kHz low-pass filter enabled, de-emphasis enabled.
// Audio impression: fuller low end, but still softened by de-emphasis and upper-frequency limiting.
//
// 0x500: 300 Hz high-pass filter disabled, 3 kHz low-pass filter enabled, de-emphasis disabled.
// Audio impression: fuller bass, more direct sound, while still keeping the 3 kHz top-end limit.
static void AUDIO_ApplyFMProfile(uint8_t profile)
{
switch (profile)
{
@@ -85,6 +100,41 @@ const char gModulationStr[MODULATION_UKNOWN][4] = {
break;
}
}
static void AUDIO_ApplyAMProfile(uint8_t profile)
{
switch (profile)
{
default:
case 0: // SHARP (ALPHA test profile) - Narrow IF filter (REG54 bits[14:8]=0, bits[7:0]=9), low IF gain (REG55 bits[11:8]=1, ref=169)
// Selective and crisp, best adjacent channel rejection, may sound harsh on strong signals
BK4819_WriteRegister(0x2b, 0x0300);
BK4819_WriteRegister(0x2f, 0x9990);
BK4819_WriteRegister(0x54, 0x9009);
BK4819_WriteRegister(0x55, 0x31A9);
break;
case 1: // STOCK - Narrow IF filter (REG54 bits[14:8]=0, bits[7:0]=9), moderate IF gain (REG55 bits[11:8]=4, ref=180)
// Selective filter with balanced gain, punchy and detailed, good compromise between rejection and sensitivity
BK4819_WriteRegister(0x2b, 0x0500);
BK4819_WriteRegister(0x2f, 0x9990);
BK4819_WriteRegister(0x54, 0x9009);
BK4819_WriteRegister(0x55, 0x31A9);
break;
case 2: // OPEN (BRAVO test profile) - Medium-wide IF filter (REG54 bits[14:8]=8, bits[7:0]=70), high IF gain (REG55 bits[11:8]=8, ref=192)
// Wide and pleasant, better sensitivity on weak signals, may struggle with adjacent channel interference
BK4819_WriteRegister(0x2b, 0x0300);
BK4819_WriteRegister(0x2f, 0x9990);
BK4819_WriteRegister(0x54, 0x8846);
BK4819_WriteRegister(0x55, 0x38C0);
break;
}
}
static void AUDIO_ApplyUSBProfile(void)
{
BK4819_WriteRegister(0x54, 0x9009);
BK4819_WriteRegister(0x55, 0x31A9);
}
#endif
bool RADIO_CheckValidList(uint8_t scanList)
@@ -1098,48 +1148,70 @@ void RADIO_SetModulation(ModulationMode_t modulation)
BK4819_SetAF(mod);
// HACK, FIXME:
//
// What follows is a direct copy of the AM enable/disable code from
// the original UV-K1 firmware. It is not clear why these specific register
// values are used for AM all of a sudden instead of the AF setting like on
// the BK4819, nor what exactly they do.
// So for now we just keep it as is to maintain compatibility.
//
if (modulation != MODULATION_AM)
switch (modulation)
{
uint16_t uVar1 = BK4819_ReadRegister(0x31);
BK4819_WriteRegister(0x31,uVar1 & 0xfffffffe);
BK4819_WriteRegister(0x42,0x6b5a);
BK4819_WriteRegister(0x2a,0x7400);
BK4819_WriteRegister(0x2b,0);
BK4819_WriteRegister(0x2f,0x9890);
//BK4819_WriteRegister(0x54, 0x9009);
//BK4819_WriteRegister(0x55, 0x31a9);
#ifdef ENABLE_FEAT_F4HWN_AUDIO
AUDIO_ApplyProfile(gSetting_set_audio);
#else
BK4819_WriteRegister(0x54, 0x9009);
BK4819_WriteRegister(0x55, 0x31a9);
#endif
}
else
{
uint16_t uVar1 = BK4819_ReadRegister(0x31);
BK4819_WriteRegister(0x31,uVar1 | 1);
BK4819_WriteRegister(0x42,0x6f5c);
BK4819_WriteRegister(0x2a,0x7434);
BK4819_WriteRegister(0x2b,0x400);
BK4819_WriteRegister(0x2f,0x9990);
//BK4819_WriteRegister(0x54, 0x9775);
//BK4819_WriteRegister(0x55, 0x32c6);
case MODULATION_AM:
{
uint16_t uVar1 = BK4819_ReadRegister(0x31);
BK4819_WriteRegister(0x31, uVar1 | 1); // AM Demodulation Enable
BK4819_WriteRegister(0x42, 0x6f5c);
BK4819_WriteRegister(0x2a, 0x7434);
//BK4819_WriteRegister(0x54, 0x8846);
//BK4819_WriteRegister(0x55, 0x38C0);
#ifdef ENABLE_FEAT_F4HWN_AUDIO
AUDIO_ApplyAMProfile(gSetting_set_audio_am);
#else
BK4819_WriteRegister(0x54, 0x9009);
BK4819_WriteRegister(0x55, 0x31a9);
#endif
BK4819_WriteRegister(0x54, 0x9009);
BK4819_WriteRegister(0x55, 0x31a9);
BK4819_SetFilterBandwidth(BK4819_FILTER_BW_AM, true);
break;
}
BK4819_SetFilterBandwidth(BK4819_FILTER_BW_AM, true);
case MODULATION_USB:
{
uint16_t uVar1 = BK4819_ReadRegister(0x31);
BK4819_WriteRegister(0x31, uVar1 & 0xfffe); // AM Demodulation Disable
BK4819_WriteRegister(0x42, 0x6b5a);
BK4819_WriteRegister(0x2a, 0x7400);
BK4819_WriteRegister(0x2b, 0x0000);
BK4819_WriteRegister(0x2f, 0x9890);
#ifdef ENABLE_FEAT_F4HWN_AUDIO
AUDIO_ApplyUSBProfile();
#else
BK4819_WriteRegister(0x54, 0x9009);
BK4819_WriteRegister(0x55, 0x31a9);
#endif
break;
}
case MODULATION_FM:
default:
{
uint16_t uVar1 = BK4819_ReadRegister(0x31);
BK4819_WriteRegister(0x31, uVar1 & 0xfffe); // AM Demodulation Disable
BK4819_WriteRegister(0x42, 0x6b5a);
BK4819_WriteRegister(0x2a, 0x7400);
BK4819_WriteRegister(0x2b, 0x0000);
BK4819_WriteRegister(0x2f, 0x9890);
#ifdef ENABLE_FEAT_F4HWN_AUDIO
AUDIO_ApplyFMProfile(gSetting_set_audio_fm);
#else
BK4819_WriteRegister(0x54, 0x9009);
BK4819_WriteRegister(0x55, 0x31a9);
#endif
break;
}
}
BK4819_SetRegValue(afDacGainRegSpec, 0xF);
@@ -1147,7 +1219,6 @@ void RADIO_SetModulation(ModulationMode_t modulation)
BK4819_SetRegValue(afcDisableRegSpec, modulation != MODULATION_FM);
RADIO_SetupAGC(modulation == MODULATION_AM, false);
//RADIO_SetupAGC(false, false);
}
void RADIO_SetupAGC(bool listeningAM, bool disable)
+3 -2
View File
@@ -121,7 +121,8 @@ void SETTINGS_InitEEPROM(void)
// 0E70..0E77
PY25Q16_ReadBuffer(0x00A000, Data, 8);
#ifdef ENABLE_FEAT_F4HWN_AUDIO
gSetting_set_audio = (Data[0] < 5) ? Data[0] : 0;
gSetting_set_audio_fm = ((Data[0] & 0x0F) < 5) ? (Data[0] & 0x0F) : 0;
gSetting_set_audio_am = (((Data[0] >> 4) & 0x0F) < 3) ? ((Data[0] >> 4) & 0x0F) : 0;
#endif
gEeprom.SQUELCH_LEVEL = (Data[1] < 10) ? Data[1] : 1;
gEeprom.TX_TIMEOUT_TIMER = (Data[2] > 4 && Data[2] < 180) ? Data[2] : 11;
@@ -764,7 +765,7 @@ void SETTINGS_SaveSettings(void)
// 0x0E70
State = SecBuf;
#ifdef ENABLE_FEAT_F4HWN_AUDIO
State[0] = gSetting_set_audio;
State[0] = (gSetting_set_audio_fm & 0x0F) | ((gSetting_set_audio_am & 0x0F) << 4);
#endif
#ifdef ENABLE_FEAT_F4HWN
if (gSquelchLevelOriginal < 10)
+12 -4
View File
@@ -897,17 +897,25 @@ void UI_DisplayMain(void)
// }
// if (RxBlink == 0 || RxBlink == 1) {
if(gRxVfo->Modulation == MODULATION_AM)
GUI_DisplaySmallest("AIR", 10, RxLine == 0 ? 1 : 33, false, true);
if(gRxVfo->Modulation == MODULATION_AM) {
#ifdef ENABLE_FEAT_F4HWN_AUDIO
strcpy(String, gSubMenu_SET_AUD_AM[gSetting_set_audio_am]);
#else
strcpy(String, "AIR");
#endif
}
else if (gRxVfo->Modulation == MODULATION_USB) {
strcpy(String, "USB");
}
else {
#ifdef ENABLE_FEAT_F4HWN_AUDIO
strcpy(String, gSubMenu_SET_AUD[gSetting_set_audio]);
strcpy(String, gSubMenu_SET_AUD_FM[gSetting_set_audio_fm]);
#else
strcpy(String, "RX");
#endif
GUI_DisplaySmallest(String, 10, RxLine == 0 ? 1 : 33, false, true);
}
GUI_DisplaySmallest(String, 10, RxLine == 0 ? 1 : 33, false, true);
//UI_PrintStringSmallBold("RX", 8, 0, RxLine);
// }
#else
+23 -5
View File
@@ -413,7 +413,7 @@ const char gSubMenu_SCRAMBLER[][7] =
};
#ifdef ENABLE_FEAT_F4HWN_AUDIO
const char gSubMenu_SET_AUD[][6] =
const char gSubMenu_SET_AUD_FM[][6] =
{
"FLAT",
"CLEAN",
@@ -421,6 +421,13 @@ const char gSubMenu_SCRAMBLER[][7] =
"BOOST",
"MAX"
};
const char gSubMenu_SET_AUD_AM[][6] =
{
"SHARP",
"STOCK",
"OPEN"
};
#endif
#ifdef ENABLE_FEAT_F4HWN_NARROWER
@@ -1194,7 +1201,18 @@ void UI_DisplayMenu(void)
#ifdef ENABLE_FEAT_F4HWN_AUDIO
case MENU_SET_AUD:
strcpy(String, gSubMenu_SET_AUD[gSubMenuSelection]);
if(gTxVfo->Modulation == MODULATION_AM) {
strcpy(String, gSubMenu_SET_AUD_AM[gSubMenuSelection]);
UI_PrintStringSmallNormal("AM", 114, 0, 0);
}
else if (gTxVfo->Modulation == MODULATION_USB) {
strcpy(String, "USB");
UI_PrintStringSmallNormal("USB", 108, 0, 0);
}
else {
strcpy(String, gSubMenu_SET_AUD_FM[gSubMenuSelection]);
UI_PrintStringSmallNormal("FM", 114, 0, 0);
}
break;
#endif
@@ -1345,8 +1363,8 @@ void UI_DisplayMenu(void)
|| UI_MENU_GetCurrentMenuId() == MENU_D_LIST
#endif
) {
sprintf(String, "%2d", gSubMenuSelection);
UI_PrintStringSmallNormal(String, 105, 0, 0);
sprintf(String, "%03d", gSubMenuSelection);
UI_PrintStringSmallNormal(String, 107, 0, 0);
}
if ((UI_MENU_GetCurrentMenuId() == MENU_RESET ||
@@ -1359,4 +1377,4 @@ void UI_DisplayMenu(void)
}
ST7565_BlitFullScreen();
}
}
+2 -1
View File
@@ -198,7 +198,8 @@ extern const char gSubMenu_D_RSP[4][11];
extern const char gSubMenu_SET_KEY[][9];
#endif
#ifdef ENABLE_FEAT_F4HWN_AUDIO
extern const char gSubMenu_SET_AUD[5][6];
extern const char gSubMenu_SET_AUD_FM[5][6];
extern const char gSubMenu_SET_AUD_AM[3][6];
#endif
#endif