Merge pull request #423 from armel/feature_update_v5

Feature update v5
This commit is contained in:
Armel FAUVEAU authored and GitHub committed 2026-06-21 19:02:08 +02:00
commit 5b4b3e2a71
14 files changed
+268 -72

No files matched your search

+8
View File
@@ -239,6 +239,9 @@ static bool ScreenSaverCanDisplay(void)
gEeprom.BACKLIGHT_TIME == 0 ||
gEeprom.BACKLIGHT_TIME >= 61 ||
gScreenSaverDisplayed ||
#ifdef ENABLE_FEAT_F4HWN_SLEEP
gWakeUp ||
#endif
gCurrentFunction == FUNCTION_TRANSMIT ||
FUNCTION_IsRx() ||
gPttIsPressed
@@ -1660,6 +1663,8 @@ void APP_TimeSlice10ms(void)
#endif
) {
SCREENSHOT_Update(false);
} else if (SCREENSHOT_HasPendingStateChange()) {
SCREENSHOT_Update(false);
}
#endif
@@ -1915,6 +1920,9 @@ void APP_TimeSlice500ms(void)
gBacklightCountdown_500ms = 0;
gPowerSave_10ms = 1;
gWakeUp = true;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
ScreenSaverExit();
#endif
// TODO:
// PWM_PLUS0_CH0_COMP = 0;
BACKLIGHT_SetBrightness(0);
+110 -14
View File
@@ -41,6 +41,101 @@ bool gScanUseCssResult;
STEP_Setting_t stepSetting;
uint8_t scanHitCount;
typedef enum
{
SCAN_FREQ_VERIFY_OFF,
SCAN_FREQ_VERIFY_FUNDAMENTAL,
SCAN_FREQ_VERIFY_HARMONIC
} SCAN_FrequencyVerifyState_t;
static SCAN_FrequencyVerifyState_t scanFreqVerifyState;
static uint32_t scanVerifyFundamental;
static uint32_t scanVerifyHarmonic;
static uint16_t scanVerifyFundamentalRssi;
static bool SCANNER_ShouldVerifyVhfSecondHarmonic(const uint32_t frequency)
{
const uint32_t fundamental = frequency / 2;
return frequency >= (frequencyBandTable[BAND3_137MHz].lower * 2) &&
frequency < (frequencyBandTable[BAND4_174MHz].lower * 2) &&
fundamental >= frequencyBandTable[BAND3_137MHz].lower &&
fundamental < frequencyBandTable[BAND4_174MHz].lower;
}
static void SCANNER_StartCssScanAtFrequency(const uint32_t frequency)
{
gScanFrequency = frequency;
gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF;
scanHitCount = 0;
gScanUseCssResult = false;
gScanProgressIndicator = 0;
gScanCssState = SCAN_CSS_STATE_SCANNING;
gScanDelay_10ms = scan_delay_10ms;
BK4819_SetScanFrequency(gScanFrequency);
if (!gCssBackgroundScan)
GUI_SelectNextDisplay(DISPLAY_SCANNER);
gUpdateStatus = true;
}
static void SCANNER_TuneForFrequencyVerification(const uint32_t frequency)
{
BK4819_SetFrequency(frequency);
BK4819_PickRXFilterPathBasedOnFrequency(frequency);
BK4819_RX_TurnOn();
}
static uint16_t SCANNER_ReadVerificationRssi(void)
{
(void)BK4819_GetRSSI();
return BK4819_GetRSSI();
}
static void SCANNER_StartFrequencyVerification(const uint32_t harmonic)
{
scanVerifyFundamental = harmonic / 2;
scanVerifyHarmonic = harmonic;
scanFreqVerifyState = SCAN_FREQ_VERIFY_FUNDAMENTAL;
SCANNER_TuneForFrequencyVerification(scanVerifyFundamental);
gScanDelay_10ms = 2;
}
static bool SCANNER_HandleFrequencyVerification(void)
{
switch (scanFreqVerifyState) {
case SCAN_FREQ_VERIFY_FUNDAMENTAL:
scanVerifyFundamentalRssi = SCANNER_ReadVerificationRssi();
scanFreqVerifyState = SCAN_FREQ_VERIFY_HARMONIC;
SCANNER_TuneForFrequencyVerification(scanVerifyHarmonic);
gScanDelay_10ms = 2;
return true;
case SCAN_FREQ_VERIFY_HARMONIC: {
const uint16_t harmonicRssi = SCANNER_ReadVerificationRssi();
const uint16_t margin = 4;
uint32_t verifiedFrequency = scanVerifyHarmonic;
if (scanVerifyFundamentalRssi > harmonicRssi &&
scanVerifyFundamentalRssi - harmonicRssi >= margin)
{
verifiedFrequency = scanVerifyFundamental;
}
scanFreqVerifyState = SCAN_FREQ_VERIFY_OFF;
SCANNER_StartCssScanAtFrequency(verifiedFrequency);
return true;
}
default:
return false;
}
}
static void SCANNER_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{
if (!bKeyHeld && bKeyPressed)
@@ -341,7 +436,8 @@ void SCANNER_Start(bool singleFreq)
gScanCssState = SCAN_CSS_STATE_OFF;
gScanFrequency = 0xFFFFFFFF;
BK4819_PickRXFilterPathBasedOnFrequency(gScanFrequency);
// Keep the RX input path selected by RADIO_SetupRegisters().
// 0xFFFFFFFF means "unknown frequency" here and would turn both LNAs off.
BK4819_SetFrequencyScan(true);
gUpdateStatus = true;
@@ -366,6 +462,7 @@ void SCANNER_Start(bool singleFreq)
g_SquelchLost = false;
gScannerSaveState = SCAN_SAVE_NO_PROMPT;
gScanProgressIndicator = 0;
scanFreqVerifyState = SCAN_FREQ_VERIFY_OFF;
}
void SCANNER_Stop(void)
@@ -377,6 +474,7 @@ void SCANNER_Stop(void)
gUpdateStatus = true;
gCssBackgroundScan = false;
gScanUseCssResult = false;
scanFreqVerifyState = SCAN_FREQ_VERIFY_OFF;
#ifdef ENABLE_VOICE
gAnotherVoiceID = VOICE_ID_CANCEL;
#endif
@@ -398,6 +496,10 @@ void SCANNER_TimeSlice10ms(void)
return;
}
if (SCANNER_HandleFrequencyVerification()) {
return;
}
switch (gScanCssState) {
case SCAN_CSS_STATE_OFF: {
// must be RF frequency scanning if we're here ?
@@ -420,22 +522,16 @@ void SCANNER_TimeSlice10ms(void)
if (scanHitCount < 3) {
BK4819_SetFrequencyScan(true);
}
else if (SCANNER_ShouldVerifyVhfSecondHarmonic(gScanFrequency)) {
SCANNER_StartFrequencyVerification(gScanFrequency);
}
else {
BK4819_SetScanFrequency(gScanFrequency);
gScanCssResultCode = 0xFF;
gScanCssResultType = 0xFF;
scanHitCount = 0;
gScanUseCssResult = false;
gScanProgressIndicator = 0;
gScanCssState = SCAN_CSS_STATE_SCANNING;
if(!gCssBackgroundScan)
GUI_SelectNextDisplay(DISPLAY_SCANNER);
gUpdateStatus = true;
SCANNER_StartCssScanAtFrequency(gScanFrequency);
}
gScanDelay_10ms = scan_delay_10ms;
if (scanFreqVerifyState == SCAN_FREQ_VERIFY_OFF) {
gScanDelay_10ms = scan_delay_10ms;
}
//gScanDelay_10ms = 1; // 10ms
break;
}
+21 -5
View File
@@ -411,6 +411,11 @@ void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet)
BK4819_WriteRegister(BK4819_REG_33, gBK4819_GpioOutState);
}
bool BK4819_IsGpioOutSet(BK4819_GPIO_PIN_t Pin)
{
return (gBK4819_GpioOutState & (0x40u >> Pin)) != 0;
}
void BK4819_SetCDCSSCodeWord(uint32_t CodeWord)
{
// REG_51
@@ -1719,7 +1724,7 @@ void BK4819_PrepareFSKReceive(void)
BK4819_WriteRegister(BK4819_REG_59, 0x3068);
}
static void BK4819_PlayRogerNormal(void)
static void BK4819_PlayRogerNormal(BK4819_FilterBandwidth_t Bandwidth)
{
#if 0
const uint32_t tone1_Hz = 500;
@@ -1734,12 +1739,19 @@ static void BK4819_PlayRogerNormal(void)
BK4819_EnterTxMute();
BK4819_SetAF(BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_70, BK4819_REG_70_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
const uint8_t rogerToneGain = (Bandwidth == BK4819_FILTER_BW_WIDE) ? 32u : 66u;
if (Bandwidth == BK4819_FILTER_BW_WIDE)
BK4819_SetFilterBandwidth(BK4819_FILTER_BW_NARROW, true);
BK4819_WriteRegister(BK4819_REG_71, scale_freq(tone1_Hz));
BK4819_EnableTXLink();
SYSTEM_DelayMs(50);
BK4819_WriteRegister(BK4819_REG_71, scale_freq(tone1_Hz));
BK4819_WriteRegister(BK4819_REG_70,
BK4819_REG_70_ENABLE_TONE1 |
(rogerToneGain << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_ExitTxMute();
SYSTEM_DelayMs(80);
@@ -1752,6 +1764,10 @@ static void BK4819_PlayRogerNormal(void)
BK4819_EnterTxMute();
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
if (Bandwidth == BK4819_FILTER_BW_WIDE)
BK4819_SetFilterBandwidth(Bandwidth, true);
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); // 1 1 0000 0 1 1111 1 1 1 0
}
@@ -1804,10 +1820,10 @@ void BK4819_PlayRogerMDC(void)
BK4819_WriteRegister(BK4819_REG_58, 0x0000);
}
void BK4819_PlayRoger(void)
void BK4819_PlayRoger(BK4819_FilterBandwidth_t Bandwidth)
{
if (gEeprom.ROGER == ROGER_MODE_ROGER) {
BK4819_PlayRogerNormal();
BK4819_PlayRogerNormal(Bandwidth);
} else if (gEeprom.ROGER == ROGER_MODE_MDC) {
BK4819_PlayRogerMDC();
}
+2 -1
View File
@@ -77,6 +77,7 @@ void BK4819_SetAGC(bool enable);
void BK4819_InitAGC(bool amModulation);
void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet);
bool BK4819_IsGpioOutSet(BK4819_GPIO_PIN_t Pin);
void BK4819_SetCDCSSCodeWord(uint32_t CodeWord);
void BK4819_SetCTCSSFrequency(uint32_t BaudRate);
@@ -169,7 +170,7 @@ uint8_t BK4819_GetCTCType(void);
void BK4819_SendFSKData(uint16_t *pData);
void BK4819_PrepareFSKReceive(void);
void BK4819_PlayRoger(void);
void BK4819_PlayRoger(BK4819_FilterBandwidth_t Bandwidth);
void BK4819_Enable_AfDac_DiscMode_TxDsp(void);
+30 -11
View File
@@ -441,6 +441,11 @@ void BK4819_ToggleGpioOut(BK4819_GPIO_PIN_t Pin, bool bSet)
BK4819_WriteRegister(BK4819_REG_33, gBK4819_GpioOutState);
}
bool BK4819_IsGpioOutSet(BK4819_GPIO_PIN_t Pin)
{
return (gBK4819_GpioOutState & (0x40u >> Pin)) != 0;
}
void BK4819_SetCDCSSCodeWord(uint32_t CodeWord)
{
// REG_51
@@ -696,11 +701,11 @@ void BK4819_SetFilterBandwidth(const BK4819_FilterBandwidth_t Bandwidth, const b
break;
case BK4819_FILTER_BW_NARROWER: // 6.25kHz
// 0x205C = (0b010 << 12) | (0b000 << 9) | (0b001 << 6) |
// (0b01 << 4) | (1 << 3) | (1 << 2)
// 0x2058 = (0b010 << 12) | (0b000 << 9) | (0b001 << 6) |
// (0b01 << 4) | (1 << 3)
// = RF 3.0 kHz, weak-RF 2.0 kHz, AF Tx LPF2 2.5 kHz,
// 6.25k mode, FM gain +6 dB.
val = 0x205C;
// 6.25k mode, FM gain 0 dB.
val = 0x2058;
break;
case BK4819_FILTER_BW_AM: // Stock AM preset
@@ -1754,7 +1759,7 @@ void BK4819_PrepareFSKReceive(void)
BK4819_WriteRegister(BK4819_REG_59, 0x3068);
}
static void BK4819_PlayRogerNormal(void)
static void BK4819_PlayRogerNormal(BK4819_FilterBandwidth_t Bandwidth)
{
#if 0
const uint32_t tone1_Hz = 500;
@@ -1769,17 +1774,31 @@ static void BK4819_PlayRogerNormal(void)
BK4819_EnterTxMute();
BK4819_SetAF(BK4819_AF_MUTE);
BK4819_WriteRegister(BK4819_REG_70, // BK4819_REG_70_ENABLE_TONE1 | (66u << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
0xC300
);
const uint8_t rogerToneGain = (Bandwidth == BK4819_FILTER_BW_WIDE) ? 32u : 67u;
if (Bandwidth == BK4819_FILTER_BW_WIDE)
BK4819_SetFilterBandwidth(BK4819_FILTER_BW_NARROW, true);
BK4819_WriteRegister(BK4819_REG_71, scale_freq(tone1_Hz));
BK4819_EnableTXLink();
SYSTEM_DelayMs(50);
BK4819_PlayToneRaw(tone1_Hz, 80);
BK4819_WriteRegister(BK4819_REG_70,
BK4819_REG_70_ENABLE_TONE1 |
(rogerToneGain << BK4819_REG_70_SHIFT_TONE1_TUNING_GAIN));
BK4819_ExitTxMute();
SYSTEM_DelayMs(80);
BK4819_EnterTxMute();
BK4819_PlayToneRaw(tone2_Hz, 80);
BK4819_WriteRegister(BK4819_REG_70, 0x0000);
if (Bandwidth == BK4819_FILTER_BW_WIDE)
BK4819_SetFilterBandwidth(Bandwidth, true);
BK4819_WriteRegister(BK4819_REG_30, 0xC1FE); // 1 1 0000 0 1 1111 1 1 1 0
}
@@ -1832,10 +1851,10 @@ void BK4819_PlayRogerMDC(void)
BK4819_WriteRegister(BK4819_REG_58, 0x0000);
}
void BK4819_PlayRoger(void)
void BK4819_PlayRoger(BK4819_FilterBandwidth_t Bandwidth)
{
if (gEeprom.ROGER == ROGER_MODE_ROGER) {
BK4819_PlayRogerNormal();
BK4819_PlayRogerNormal(Bandwidth);
} else if (gEeprom.ROGER == ROGER_MODE_MDC) {
BK4819_PlayRogerMDC();
}
+10 -1
View File
@@ -1328,7 +1328,16 @@ void RADIO_SendCssTail(void)
void RADIO_SendEndOfTransmission(void)
{
BK4819_PlayRoger();
BK4819_FilterBandwidth_t Bandwidth = gCurrentVfo->CHANNEL_BANDWIDTH;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
if(Bandwidth == BK4819_FILTER_BW_NARROW && gSetting_set_nfm == 1)
{
Bandwidth = BK4819_FILTER_BW_NARROWER;
}
#endif
BK4819_PlayRoger(Bandwidth);
DTMF_SendEndOfTransmission();
// send the CTCSS/DCS tail tone - allows the receivers to mute the usual FM squelch tail/crash
+48 -8
View File
@@ -20,6 +20,7 @@
#include "misc.h"
#include "driver/vcp.h"
#include "driver/keyboard.h"
#include "driver/bk4819.h"
// SRAM optimization: minimize static allocations
// - previousHash: one fingerprint per 8-byte chunk instead of a full
@@ -35,8 +36,11 @@
// transforming each transmitted chunk twice (negligible next to the
// blocking UART transfer).
static uint16_t previousHash[128];
static uint8_t previousStateFlags = 0xFF;
static uint8_t forcedBlock = 0;
static uint8_t keepAlive = 3;
static bool hasConnectionPing = false;
static bool wasConnected = false;
// FNV-1a over one 8-byte chunk, folded to 16 bits
static uint16_t SCREENSHOT_Hash(const uint8_t *data)
@@ -55,10 +59,12 @@ void SCREENSHOT_ParseInput(void)
if (UART_IsCableConnected()) {
keepAlive = 15;
hasConnectionPing = true;
gUSB_ScreenshotEnabled = false;
}
else if (VCP_ScreenshotPing()) {
keepAlive = 15;
hasConnectionPing = true;
gUSB_ScreenshotEnabled = true;
}
}
@@ -76,8 +82,38 @@ enum {
SCREENSHOT_CHUNK_SIZE = 8,
SCREENSHOT_CHUNKS_PER_LINE = 16,
SCREENSHOT_HALF_LINE_COLUMNS = LCD_WIDTH / 2,
SCREENSHOT_MARKER_BASE = 0xF0,
SCREENSHOT_FLAG_DEEP_SLEEP = 1 << 0,
SCREENSHOT_FLAG_LED_RED = 1 << 1,
SCREENSHOT_FLAG_LED_GREEN = 1 << 2,
};
static uint8_t SCREENSHOT_StateFlags(void)
{
uint8_t flags = 0;
#ifdef ENABLE_FEAT_F4HWN_SLEEP
if (gWakeUp)
flags |= SCREENSHOT_FLAG_DEEP_SLEEP;
#endif
if (BK4819_IsGpioOutSet(BK4819_GPIO5_PIN1_RED))
flags |= SCREENSHOT_FLAG_LED_RED;
if (BK4819_IsGpioOutSet(BK4819_GPIO6_PIN2_GREEN))
flags |= SCREENSHOT_FLAG_LED_GREEN;
return flags;
}
bool SCREENSHOT_HasPendingStateChange(void)
{
if (gUART_LockScreenshot > 0 || keepAlive == 0 || !hasConnectionPing)
return false;
return !wasConnected || SCREENSHOT_StateFlags() != previousStateFlags;
}
// Compute one 8-byte output chunk directly from the display buffers.
// Frame layout: per line (status + 7 frame lines), 8 bit layers of
// 16 bytes each. Each bit layer is split into two 64-column chunks.
@@ -101,8 +137,6 @@ static void SCREENSHOT_Chunk(uint8_t chunkIdx, uint8_t *dest)
void SCREENSHOT_Update(bool force)
{
static bool wasConnected = false;
if (SCREENSHOT_IsLocked())
return;
@@ -110,6 +144,8 @@ void SCREENSHOT_Update(bool force)
if (--keepAlive == 0) {
// Connection just lost → reset state for next reconnection
wasConnected = false;
hasConnectionPing = false;
previousStateFlags = 0xFF;
return;
}
} else {
@@ -119,9 +155,11 @@ void SCREENSHOT_Update(bool force)
// Connection is alive — detect reconnection and force full frame
if (!wasConnected) {
force = true;
wasConnected = true;
}
const uint8_t stateFlags = SCREENSHOT_StateFlags();
const bool stateChanged = (stateFlags != previousStateFlags);
// ==== FIRST PASS: Count changed chunks ====
uint16_t deltaLen = 0;
uint8_t changedBitmap[16] = {0}; // 1 bit per chunk
@@ -141,7 +179,7 @@ void SCREENSHOT_Update(bool force)
forcedBlock = (forcedBlock + 1) % 128;
if (deltaLen == 0)
if (deltaLen == 0 && !stateChanged)
return;
// Skip transmission if a key is currently pressed
@@ -149,10 +187,9 @@ void SCREENSHOT_Update(bool force)
if (gKeyReading0 != KEY_INVALID)
return;
// ==== Send version marker (for backward compatibility detection) ====
// New format: sends 0xFF before header
// Old format: doesn't exist, so viewers can differentiate
uint8_t versionMarker = 0xFF;
// ==== Send version marker and state flags ====
// 0xF0 keeps a resync-safe marker before the standard AA 55 header.
uint8_t versionMarker = SCREENSHOT_MARKER_BASE | stateFlags;
SCREENSHOT_Send(&versionMarker, 1);
// ==== Send header ====
@@ -183,4 +220,7 @@ void SCREENSHOT_Update(bool force)
uint8_t end = 0x0A;
SCREENSHOT_Send(&end, 1);
previousStateFlags = stateFlags;
wasConnected = true;
}
+2 -1
View File
@@ -19,5 +19,6 @@
void SCREENSHOT_Update(bool force);
void SCREENSHOT_ParseInput(void);
bool SCREENSHOT_HasPendingStateChange(void);
#endif
#endif
+4 -3
View File
@@ -455,15 +455,16 @@ gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data16[5]) ? Data16[5] : (FREQ_CHANNE
// TODO: address TBD
PY25Q16_ReadBuffer(0x00A158, Data, 8);
const uint8_t set_ptt_scn_sav = Data[7] & 0x0F;
const bool set_ptt_scn_sav_erased = Data[7] == 0xFF;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
const bool set_ptt_scn_sav_valid = set_ptt_scn_sav < (SET_SAV_LEN << 2);
const bool set_ptt_scn_sav_valid = !set_ptt_scn_sav_erased && set_ptt_scn_sav < (SET_SAV_LEN << 2);
#else
const bool set_ptt_scn_sav_valid = set_ptt_scn_sav < 4;
const bool set_ptt_scn_sav_valid = !set_ptt_scn_sav_erased && set_ptt_scn_sav < 4;
#endif
gSetting_set_pwr = (((Data[7] & 0xF0) >> 4) < 7) ? ((Data[7] & 0xF0) >> 4) : 0;
gSetting_set_ptt = set_ptt_scn_sav_valid ? (set_ptt_scn_sav & 0x01) : 0;
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
gSetting_set_scn = set_ptt_scn_sav_valid ? ((set_ptt_scn_sav & 0x02) == 0) : 1;
gSetting_set_scn = set_ptt_scn_sav_valid ? ((set_ptt_scn_sav & 0x02) == 0) : 0;
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
gSetting_set_sav = set_ptt_scn_sav_valid ? ((set_ptt_scn_sav >> 2) & 0x03) : SET_SAV_OFF;
+31 -26
View File
@@ -262,9 +262,17 @@ void UI_DisplayStatus()
else if (gBackLight) {
// Distinguish the manual backlight sub-state: BACKLIGHT_TIME == 0
// means the light is currently off (hollow bulb), otherwise it is
// forced on (bulb with filament). Both glyphs share the same size.
src = (gEeprom.BACKLIGHT_TIME == 0) ? gFontLightOff : gFontLight;
size = sizeof(gFontLight);
// forced on (bulb with filament).
if (gEeprom.BACKLIGHT_TIME == 0) {
src = gFontLightOff;
size = sizeof(gFontLightOff);
}
else
{
src = gFontLight;
size = sizeof(gFontLight);
}
}
#ifdef ENABLE_FEAT_F4HWN_CHARGING_C
else if (gChargingWithTypeC) {
@@ -283,38 +291,35 @@ void UI_DisplayStatus()
UI_DrawBattery(line + x2, gBatteryDisplayLevel, gLowBatteryBlink);
bool BatTxt = true;
switch (gSetting_battery_text) {
default:
case 0:
BatTxt = false;
break;
case 1: // voltage
const uint16_t voltage = MIN(gBatteryVoltageAverage, 999); // limit to 9.99V
sprintf(str, "%u.%02u", voltage / 100, voltage % 100);
break;
case 1: // voltage
case 2: // percentage
//gBatteryVoltageAverage = 999;
sprintf(str, "%02u%%", BATTERY_VoltsToPercent(gBatteryVoltageAverage));
if (gSetting_battery_text == 1) {
const uint16_t voltage = MIN(gBatteryVoltageAverage, 999); // limit to 9.99V
sprintf(str, "%u.%02u", voltage / 100, voltage % 100);
} else {
//gBatteryVoltageAverage = 999;
sprintf(str, "%02u%%", BATTERY_VoltsToPercent(gBatteryVoltageAverage));
}
x2 -= (7 * strlen(str));
UI_PrintStringSmallBufferNormal(str, line + x2);
/*
uint8_t shift = (strlen(str) < 5) ? 92 : 88;
GUI_DisplaySmallest(str, shift, 1, true, true);
for (uint8_t i = shift - 2; i < 110; i++) {
gStatusLine[i] ^= 0x7F; // invert
}
*/
break;
}
if (BatTxt) {
x2 -= (7 * strlen(str));
UI_PrintStringSmallBufferNormal(str, line + x2);
/*
uint8_t shift = (strlen(str) < 5) ? 92 : 88;
GUI_DisplaySmallest(str, shift, 1, true, true);
for (uint8_t i = shift - 2; i < 110; i++) {
gStatusLine[i] ^= 0x7F; // invert
}
*/
}
// **************
ST7565_BlitStatusLine();
+1 -1
View File
@@ -79,7 +79,7 @@
"ENABLE_UART_RW_BK_REGS": false,
"ENABLE_SWD": false,
"VERSION_STRING_1": "v0.22",
"VERSION_STRING_2": "v5.6.0"
"VERSION_STRING_2": "v5.6.1"
}
},
{
+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 (2 times), Zhuo BG7SGA, Jamie M0JLB, Antoine LIBERT, Vince K0DKR, Julia DF7JA, Ken 2E0UMK, Victor TI2SYS, Tobi DG9LAY, Deaglan K4DFQ, Catherine PALMER, Brian WA6JFK, Stéphane Hintzy, Roger F1HCN, Marcin Kusaj and Flavio Cottarelli 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 / F4WFS (3 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 (2 times), Zhuo BG7SGA, Jamie M0JLB, Antoine LIBERT, Vince K0DKR, Julia DF7JA, Ken 2E0UMK, Victor TI2SYS, Tobi DG9LAY, Deaglan K4DFQ, Catherine PALMER, Brian WA6JFK, Stéphane Hintzy, Roger F1HCN, Marcin Kusaj, Flavio Cottarelli and Bob N1MLZ for their [donations](https://www.paypal.com/paypalme/F4HWN). That’s so kind of them. Thanks so much 🙏🏻
## Table of Contents
BIN
View File
Binary file not shown.
Binary file not shown.