Compare commits

...
15 Commits
Author SHA1 Message Date
Armel FAUVEAU 086858945b Merge pull request #133 from armel/feature_update_v4
Feature update v4
2026-02-05 23:42:07 +01:00
Armel FAUVEAU df99e6dc1f New version 5.1.0 2026-02-05 23:39:37 +01:00
Armel FAUVEAU 5ee5ec8873 Prepare new version 2026-02-05 23:15:20 +01:00
Armel FAUVEAU 5170170bb1 Fix spectrum RenderStill() 2026-02-05 05:11:00 +01:00
Armel FAUVEAU 76c48044c8 Shift BITMAP_VFO_Lock 2026-02-05 00:24:33 +01:00
Armel FAUVEAU ead079dc5b Update donors 2026-02-04 13:36:50 +01:00
Armel FAUVEAU add6fb17ed Fix SETTINGS_ResetTxLock() 2026-02-04 13:22:59 +01:00
Armel FAUVEAU c4079b1c32 Oops add reset display inversion (SET_INV = 0) 2026-02-04 02:12:45 +01:00
Armel FAUVEAU c4fb7de972 Fix FM_EraseChannels() 2026-02-03 04:08:53 +01:00
Armel FAUVEAU 45ead3125f Fix Lines 1 & 2 evil bug 2026-02-03 02:44:31 +01:00
Armel FAUVEAU 2b40d1216e Fix RO evil bug on new install 2026-02-03 01:57:38 +01:00
Armel FAUVEAU e555b48811 Fix TXLock icon 2026-02-02 22:19:38 +01:00
muzkr d70cc8f59a Refine systick config 2026-02-03 00:51:32 +08:00
Armel FAUVEAU cd79144a25 Add Fusion v5.0.2 public beta 2026-02-01 23:06:17 +01:00
Armel FAUVEAU b7151de126 Add new binary 2026-02-01 23:02:57 +01:00
13 changed files with 115 additions and 40 deletions

No files matched your search

+1 -1
View File
@@ -88,7 +88,7 @@ DECLARE_AIRCOPY_BANK(1)
// For settings only
static const AIRCOPY_Segment_t AIRCOPY_Segments_Settings[] = {
{ 0xA000, 0xA160, AIRCOPY_WRITE_BYTES },
{ 0xA000, 0xA170, AIRCOPY_WRITE_BYTES },
};
static const AIRCOPY_TransferMap_t AIRCOPY_Map_Settings = {
+6 -1
View File
@@ -120,7 +120,12 @@ void FM_TurnOff(void)
void FM_EraseChannels(void)
{
PY25Q16_SectorErase(0x003000);
//PY25Q16_SectorErase(0x003000);
uint8_t clearBuf[128];
memset(clearBuf, 0xFF, sizeof(clearBuf));
PY25Q16_WriteBuffer(0x00A028, clearBuf, sizeof(clearBuf), false);
memset(gFM_Channels, 0xFF, sizeof(gFM_Channels));
}
+17 -19
View File
@@ -103,8 +103,8 @@ RegisterSpec registerSpecs[] = {
{},
{"LNAs", BK4819_REG_13, 8, 0b11, 1},
{"LNA", BK4819_REG_13, 5, 0b111, 1},
{"VGA", BK4819_REG_13, 0, 0b111, 1},
{"BPF", BK4819_REG_3D, 0, 0xFFFF, 0x2aaa},
{"PGA", BK4819_REG_13, 0, 0b111, 1},
//{"BPF", BK4819_REG_3D, 0, 0xFFFF, 0x2aaa},
// {"MIX", 0x13, 3, 0b11, 1}, // TODO: hidden
};
@@ -112,7 +112,7 @@ RegisterSpec registerSpecs[] = {
const int8_t LNAsOptions[] = {-19, -16, -11, 0};
const int8_t LNAOptions[] = {-24, -19, -14, -9, -6, -4, -2, 0};
const int8_t VGAOptions[] = {-33, -27, -21, -15, -9, -6, -3, 0};
const char *BPFOptions[] = {"8.46", "7.25", "6.35", "5.64", "5.08", "4.62", "4.23"};
//const char *BPFOptions[] = {"8.46", "7.25", "6.35", "5.64", "5.08", "4.62", "4.23"};
#endif
uint16_t statuslineUpdateTimer = 0;
@@ -1185,6 +1185,8 @@ static void DrawArrow(uint8_t x)
static void OnKeyDown(uint8_t key)
{
bool nav = (gEeprom.SET_NAV != 0);
switch (key)
{
case KEY_3:
@@ -1209,10 +1211,7 @@ static void OnKeyDown(uint8_t key)
#ifdef ENABLE_SCAN_RANGES
if (!gScanRangeStart) {
#endif
if(gEeprom.SET_NAV == 0)
UpdateCurrentFreq(false);
else
UpdateCurrentFreq(true);
UpdateCurrentFreq(nav);
#ifdef ENABLE_SCAN_RANGES
}
#endif
@@ -1221,10 +1220,7 @@ static void OnKeyDown(uint8_t key)
#ifdef ENABLE_SCAN_RANGES
if (!gScanRangeStart) {
#endif
if(gEeprom.SET_NAV == 0)
UpdateCurrentFreq(true);
else
UpdateCurrentFreq(false);
UpdateCurrentFreq(!nav);
#ifdef ENABLE_SCAN_RANGES
}
#endif
@@ -1334,6 +1330,8 @@ static void OnKeyDownFreqInput(uint8_t key)
void OnKeyDownStill(KEY_Code_t key)
{
bool nav = (gEeprom.SET_NAV != 0);
switch (key)
{
case KEY_3:
@@ -1344,19 +1342,17 @@ void OnKeyDownStill(KEY_Code_t key)
break;
case KEY_UP:
if (menuState) {
bool nav = (gEeprom.SET_NAV != 0);
SetRegMenuValue(menuState, nav);
UpdateCurrentFreqStill(nav);
break;
}
UpdateCurrentFreqStill(nav);
break;
case KEY_DOWN:
if (menuState) {
bool nav = (gEeprom.SET_NAV != 0);
SetRegMenuValue(menuState, !nav);
UpdateCurrentFreqStill(!nav);
break;
}
UpdateCurrentFreqStill(!nav);
break;
case KEY_STAR:
UpdateRssiTriggerLevel(true);
@@ -1475,9 +1471,9 @@ static void RenderStill()
uint8_t offset = PAD_LEFT;
uint8_t row = 4;
for (int i = 0, idx = 1; idx <= 4; ++i, ++idx)
for (int i = 0, idx = 1; idx <= 3; ++i, ++idx)
{
if (idx == 5)
if (idx == 4)
{
row += 2;
i = 0;
@@ -1508,10 +1504,12 @@ static void RenderStill()
{
sprintf(String, "%ddB", VGAOptions[GetRegMenuValue(idx)]);
}
/*
else if(idx == 4)
{
sprintf(String, "%skHz", BPFOptions[(GetRegMenuValue(idx) / 0x2aaa)]);
}
*/
#else
sprintf(String, "%u", GetRegMenuValue(idx));
#endif
+7 -7
View File
@@ -168,13 +168,13 @@ const uint8_t BITMAP_Antenna[5] =
const uint8_t BITMAP_VFO_Lock[7] =
{
0b01111100,
0b01000110,
0b01000101,
0b01000101,
0b01000101,
0b01000110,
0b01111100,
0b00111100,
0b00100110,
0b00100101,
0b00100101,
0b00100101,
0b00100110,
0b00111100,
};
const uint8_t BITMAP_VFO_Default[7] =
+2 -1
View File
@@ -52,7 +52,7 @@ static const AddrMapping_t ADDR_MAPPINGS[] = {
_MK_MAPPING(0x009000, 0x009000, 0x0090D6), // 14 VFO * 16 Bytes (ex 0x001000)
_MK_MAPPING(0x00A000, 0x00A000, 0x00A160), // Settings * 16 Bytes (ex 0x004000) 0x00A000 -> 0x00A010
_MK_MAPPING(0x00A000, 0x00A000, 0x00A170), // Settings * 16 Bytes (ex 0x004000) 0x00A000 -> 0x00A010
// Settings * 16 Bytes (ex 0x005000) 0x00A010 -> 0x00A020
// Settings FM * 8 Bytes (0x006000) 0x00A020 -> 0x00A028
// MR FM * 128 Bytes (0x003000) 0x00A028 -> 0x00A0A8
@@ -62,6 +62,7 @@ static const AddrMapping_t ADDR_MAPPINGS[] = {
// Settings AES * 16 Bytes (0x00A000) 0x00A140 -> 0x00A150
// Settings * 8 Bytes (0x00B000) 0x00A150 -> 0x00A158
// Settings F4HWN * 8 Bytes (0x00C000) 0x00A158 -> 0x00A160
// Settings Version * 16 Bytes 0x00A160 -> 0x00A170
_MK_MAPPING(0x010000, 0x00B000, 0x00B200), // Calibration 512 Bytes!!!
};
+3 -2
View File
@@ -20,8 +20,9 @@
static uint32_t gTickMultiplier;
void SYSTICK_Init(void)
{
SysTick_Config(480000);
gTickMultiplier = 48;
SysTick_Config(SystemCoreClock / 100); // 10 ms (1/100 sec) systick interrupt
gTickMultiplier = SystemCoreClock / 1000000;
NVIC_SetPriority(SysTick_IRQn, 0);
}
void SYSTICK_DelayUs(uint32_t Delay)
+74 -4
View File
@@ -33,6 +33,73 @@ EEPROM_Config_t gEeprom = { 0 };
void SETTINGS_InitEEPROM(void)
{
uint8_t Data[16] = {0};
//
// Version check
// Read stored version from EEPROM and compare with VERSION_STRING_2
//
{
char storedVersion[16] = {0};
PY25Q16_ReadBuffer(0x00A160, storedVersion, sizeof(storedVersion));
// Compare with current version
if (strncmp(storedVersion, VERSION_STRING_2, sizeof(storedVersion)) != 0)
{
// Different version: new install or firmware update
// 1. Write new version to EEPROM
char newVersion[16] = {0};
strncpy(newVersion, VERSION_STRING_2, sizeof(newVersion));
PY25Q16_WriteBuffer(0x00A160, newVersion, sizeof(newVersion), false);
// 2. Reset sensitive parameters (MENU_LOCK, etc.)
uint8_t configByte[8] = {0};
PY25Q16_ReadBuffer(0x00A000, configByte, sizeof(configByte));
configByte[4] &= (uint8_t)~0x01; // KEY_LOCK = 0
configByte[4] &= (uint8_t)~0x02; // MENU_LOCK = 0
configByte[4] &= (uint8_t)~0x3C; // SET_KEY = 0
configByte[4] &= (uint8_t)~0x40; // SET_NAV = 0
PY25Q16_WriteBuffer(0x00A000, configByte, sizeof(configByte), false);
// 3. Reset display inversion (SET_INV = 0)
uint8_t displayByte[8] = {0};
PY25Q16_ReadBuffer(0x00A158, displayByte, sizeof(displayByte));
displayByte[5] &= (uint8_t)~0x10; // Clear bit 4 (SET_INV)
PY25Q16_WriteBuffer(0x00A158, displayByte, sizeof(displayByte), false);
// 4. Reset logo lines (clear to null for strlen() == 0)
char logoLines[32];
PY25Q16_ReadBuffer(0x00A0C8, logoLines, sizeof(logoLines));
bool needsWrite = false;
for (int line = 0; line < 2; line++) {
int offset = line * 16;
for (int i = 0; i < 16; i++) {
char c = logoLines[offset + i];
if (c == 0) {
break;
}
if (c < 0x20 || c > 0x7E) {
memset(logoLines + offset, 0, 16);
needsWrite = true;
break;
}
}
}
if (needsWrite) {
PY25Q16_WriteBuffer(0x00A0C8, logoLines, sizeof(logoLines), false);
}
}
}
// 0E70..0E77
PY25Q16_ReadBuffer(0x00A000, Data, 8);
#ifdef ENABLE_FEAT_F4HWN_AUDIO
@@ -1186,12 +1253,12 @@ void SETTINGS_ResetTxLock(void)
// This is an expensive operation: full scan of all MR channels
#define CHANNEL_SIZE 16
#define TXLOCK_BYTE_OFFSET 4
#define TXLOCK_BYTE_OFFSET 12
#define TXLOCK_BIT 6
#define SETTINGS_ResetTxLock_BATCH 16
#define SETTINGS_ResetTxLock_BATCH 32
const uint32_t TotalBytes = MR_CHANNELS_MAX * CHANNEL_SIZE; // 512 * 16 = 8192
const uint32_t BatchSize = TotalBytes / SETTINGS_ResetTxLock_BATCH; // 8192 / 16 = 512
const uint32_t TotalBytes = MR_CHANNELS_MAX * CHANNEL_SIZE; // 1024 * 16 = 16 384
const uint32_t BatchSize = TotalBytes / SETTINGS_ResetTxLock_BATCH; // 16 384 / 32 = 512
const uint32_t BatchChCnt = BatchSize / CHANNEL_SIZE; // 32 channels per batch
uint8_t Buf[BatchSize];
@@ -1211,6 +1278,9 @@ void SETTINGS_ResetTxLock(void)
PY25Q16_WriteBuffer(Offset, Buf, BatchSize, false);
}
RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
#undef SETTINGS_ResetTxLock_BATCH
#undef CHANNEL_SIZE
#undef TXLOCK_BYTE_OFFSET
+3 -3
View File
@@ -741,12 +741,12 @@ void UI_DisplayMain(void)
uint32_t frequency = gEeprom.VfoInfo[vfo_num].pRX->Frequency;
if(TX_freq_check(frequency) != 0 && gEeprom.VfoInfo[vfo_num].TX_LOCK == true)
if(TX_freq_check(frequency) != 0 && gEeprom.VfoInfo[vfo_num].TX_LOCK == true && !FUNCTION_IsRx())
{
if(isMainOnly())
memcpy(p_line0 + 14, BITMAP_VFO_Lock, sizeof(BITMAP_VFO_Lock));
memcpy(p_line0 + 25, BITMAP_VFO_Lock, sizeof(BITMAP_VFO_Lock));
else
memcpy(p_line0 + 24, BITMAP_VFO_Lock, sizeof(BITMAP_VFO_Lock));
memcpy(p_line0 + 25, BITMAP_VFO_Lock, sizeof(BITMAP_VFO_Lock));
}
if (gCurrentFunction == FUNCTION_TRANSMIT)
+1 -1
View File
@@ -69,7 +69,7 @@
"ENABLE_UART_RW_BK_REGS": false,
"ENABLE_SWD": false,
"VERSION_STRING_1": "v0.22",
"VERSION_STRING_2": "v5.0.2"
"VERSION_STRING_2": "v5.1.0"
}
},
{
+1 -1
View File
@@ -42,7 +42,7 @@ Anyway, have fun.
# Donations
Special thanks to Jean-Cyrille F6IWW (3 times), Fabrice 14RC123, David F4BPP, Olivier 14RC206, Frédéric F4ESO, Stéphane F5LGW (2 times), Jorge Ornelas (4 times), Laurent F4AXK, Christophe Morel, Clayton W0LED, Pierre Antoine F6FWB, Jean-Claude 14FRS3306, Thierry F4GVO, Eric F1NOU, PricelessToolkit, Ady M6NYJ, Tom McGovern (4 times), Joseph Roth, Pierre-Yves Colin, Frank DJ7FG, Marcel Testaz, Brian Frobisher, Yannick F4JFO, Paolo Bussola, Dirk DL8DF, Levente Szőke (2 times), Bernard-Michel Herrera, Jérôme Saintespes, Paul Davies, RS (3 times), Johan F4WAT, Robert Wörle, Rafael Sundorf, Paul Harker, Peter Fintl, Pascal F4ICR (2 times), Mike DL2MF (3 times), Eric KI1C (2 times), Phil G0ELM, Jérôme Lambert, Eliot Vedel, Alfonso EA7KDF, Jean-François F1EVM, Robert DC1RDB (2 times), Ian KE2CHJ, Daryl VK3AWA, Roberto Brunelli, Robert Boardman, Stephen Oliver, Nicolas F4INE, William Bruno, Daniel OK2VLK, Tayler Chew, Peter DL7RFP, Philippe Kopp, Rune LA6YMA, Jeremy Luna, Steef Wagenaar and Zhuo BG7SGA for their [donations](https://www.paypal.com/paypalme/F4HWN). That’s so kind of them. Thanks so much 🙏🏻
Special thanks to Jean-Cyrille F6IWW (3 times), Fabrice 14RC123, David F4BPP, Olivier 14RC206, Frédéric F4ESO, Stéphane F5LGW (2 times), Jorge Ornelas (4 times), Laurent F4AXK, Christophe Morel, Clayton W0LED, Pierre Antoine F6FWB, Jean-Claude 14FRS3306, Thierry F4GVO, Eric F1NOU, PricelessToolkit, Ady M6NYJ, Tom McGovern (4 times), Joseph Roth, Pierre-Yves Colin, Frank DJ7FG, Marcel Testaz, Brian Frobisher, Yannick F4JFO, Paolo Bussola, Dirk DL8DF, Levente Szőke (2 times), Bernard-Michel Herrera, Jérôme Saintespes, Paul Davies, RS (3 times), Johan F4WAT, Robert Wörle, Rafael Sundorf, Paul Harker, Peter Fintl, Pascal F4ICR (2 times), Mike DL2MF (3 times), Eric KI1C (2 times), Phil G0ELM, Jérôme Lambert, Eliot Vedel, Alfonso EA7KDF, Jean-François F1EVM, Robert DC1RDB (2 times), Ian KE2CHJ, Daryl VK3AWA, Roberto Brunelli, Robert Boardman, Stephen Oliver, Nicolas F4INE, William Bruno, Daniel OK2VLK, Tayler Chew, Peter DL7RFP, Philippe Kopp, Rune LA6YMA, Jeremy Luna, Steef Wagenaar, Zhuo BG7SGA and Jamie M0JLB for their [donations](https://www.paypal.com/paypalme/F4HWN). That’s so kind of them. Thanks so much 🙏🏻
## Table of Contents
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.