Add SetSav BLMin screensaver

This commit is contained in:
Armel FAUVEAU committed 2026-05-12 18:01:46 +02:00
1 parent 1589d8bdd7
commit fa75ab4243
13 files changed
+278 -13

No files matched your search

+5
View File
@@ -215,6 +215,11 @@ if(ENABLE_FEAT_F4HWN_BEAM AND NOT ENABLE_AIRCOPY)
endif()
enable_feature(ENABLE_FEAT_F4HWN_QRCODE)
enable_feature(ENABLE_FEAT_F4HWN_LOGO)
enable_feature(ENABLE_FEAT_F4HWN_LOGO_SAV)
if(ENABLE_FEAT_F4HWN_LOGO_SAV AND NOT ENABLE_FEAT_F4HWN_LOGO)
message(FATAL_ERROR "ENABLE_FEAT_F4HWN_LOGO_SAV requires ENABLE_FEAT_F4HWN_LOGO.")
endif()
# ---- DEBUGGING ----
+172
View File
@@ -72,11 +72,13 @@
#include "sram-overlay.h"
#endif
#include "ui/battery.h"
#include "ui/helper.h"
#include "ui/inputbox.h"
#include "ui/main.h"
#include "ui/menu.h"
#include "ui/status.h"
#include "ui/ui.h"
#include "ui/welcome.h"
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
#include "screenshot.h"
@@ -86,6 +88,16 @@ static bool flagSaveVfo;
static bool flagSaveSettings;
static bool flagSaveChannel;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
static bool gScreenSaverDisplayed;
static uint8_t gScreenSaverMode;
static uint8_t gScreenSaverTick;
static uint16_t gMatrixRandom = 0xACE1;
static uint8_t gMatrixHeads[32];
static uint8_t gMatrixSpeeds[32];
static KEY_Code_t gScreenSaverWakeKey = KEY_INVALID;
#endif
static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
@@ -110,11 +122,118 @@ static_assert(ARRAY_SIZE(ProcessKeysFunctions) == DISPLAY_N_ELEM-1);
static_assert(ARRAY_SIZE(ProcessKeysFunctions) == DISPLAY_N_ELEM);
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
static uint8_t ScreenSaverRandom(void)
{
gMatrixRandom = (uint16_t)(gMatrixRandom * 2053u + 13849u);
return (uint8_t)(gMatrixRandom >> 8);
}
static void ScreenSaverSetPixel(uint8_t x, uint8_t y, bool fill)
{
const uint8_t pattern = 1u << (y & 7u);
if (y < 8) {
if (fill)
gStatusLine[x] |= pattern;
else
gStatusLine[x] &= (uint8_t)~pattern;
return;
}
y -= 8;
if (fill)
gFrameBuffer[y >> 3][x] |= pattern;
else
gFrameBuffer[y >> 3][x] &= (uint8_t)~pattern;
}
static void ScreenSaverDrawMatrixGlyph(uint8_t x, int16_t y, uint8_t glyph)
{
static const uint8_t glyphs[][3] = {
{0x1F, 0x11, 0x1F},
{0x15, 0x1F, 0x15},
{0x1D, 0x15, 0x17},
{0x17, 0x15, 0x1D},
{0x1F, 0x04, 0x1F},
{0x1B, 0x15, 0x1B},
{0x0E, 0x11, 0x0E},
{0x11, 0x0A, 0x04}
};
for (uint8_t dx = 0; dx < 3; dx++) {
uint8_t pixels = glyphs[glyph & 7u][dx];
for (uint8_t dy = 0; dy < 5; dy++) {
const int16_t py = y + dy;
if ((pixels & (1u << dy)) && py >= 0 && py < LCD_HEIGHT)
ScreenSaverSetPixel(x + dx, (uint8_t)py, true);
}
}
}
static void ScreenSaverRenderMatrix(bool reset)
{
if (reset) {
for (uint8_t i = 0; i < ARRAY_SIZE(gMatrixHeads); i++) {
gMatrixHeads[i] = ScreenSaverRandom() % 112u;
gMatrixSpeeds[i] = 1u + (ScreenSaverRandom() % 3u);
}
} else {
for (uint8_t i = 0; i < ARRAY_SIZE(gMatrixHeads); i++) {
gMatrixHeads[i] += gMatrixSpeeds[i];
if (gMatrixHeads[i] > 112u)
gMatrixHeads[i] = ScreenSaverRandom() & 0x0Fu;
}
}
UI_StatusClear();
UI_DisplayClear();
for (uint8_t col = 0; col < ARRAY_SIZE(gMatrixHeads); col++) {
const uint8_t x = col * 4u;
for (uint8_t trail = 0; trail < 8; trail++) {
const int16_t y = (int16_t)gMatrixHeads[col] - ((int16_t)trail * 7);
const uint8_t glyph = (uint8_t)(col + trail + gMatrixHeads[col]);
if (trail == 0) {
ScreenSaverDrawMatrixGlyph(x, y, glyph);
} else if ((trail < 4) || ((glyph & 1u) != 0)) {
ScreenSaverDrawMatrixGlyph(x, y, glyph);
}
}
}
ST7565_BlitStatusLine();
ST7565_BlitFullScreen();
}
static void ScreenSaverExit(void)
{
if (gScreenSaverDisplayed) {
gScreenSaverDisplayed = false;
gUpdateDisplay = true;
}
}
#endif
bool APP_IsScreenSaverDisplayed(void)
{
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
return gScreenSaverDisplayed;
#else
return false;
#endif
}
static void CheckForIncoming(void)
{
if (!g_SquelchLost)
return; // squelch is closed
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
ScreenSaverExit();
#endif
// squelch is open
if (gScanStateDir == SCAN_OFF)
@@ -495,6 +614,10 @@ void APP_StartListening(FUNCTION_Type_t function)
{
const unsigned int vfo = gEeprom.RX_VFO;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
ScreenSaverExit();
#endif
#ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER
gRxTimerCountdown_500ms = 7200;
#endif
@@ -1414,6 +1537,23 @@ void APP_TimeSlice10ms(void)
bool gUpdateDisplayCurrent = gUpdateDisplay;
bool gUpdateStatusCurrent = gUpdateStatus;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
if (gScreenSaverDisplayed && gUpdateDisplayCurrent) {
gUpdateDisplayCurrent = false;
gUpdateDisplay = false;
} else if (gScreenSaverDisplayed && gUpdateStatusCurrent) {
gUpdateStatusCurrent = false;
gUpdateStatus = false;
}
if (gScreenSaverDisplayed && gScreenSaverMode == SET_SAV_MATRIX && !gUpdateDisplayCurrent) {
if (++gScreenSaverTick >= 8u) {
gScreenSaverTick = 0;
ScreenSaverRenderMatrix(false);
}
}
#endif
if (gUpdateDisplayCurrent) {
gUpdateDisplay = false;
GUI_DisplayScreen();
@@ -1634,6 +1774,20 @@ void APP_TimeSlice500ms(void)
&& gEeprom.BACKLIGHT_TIME < 61
) {
BACKLIGHT_TurnOff();
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
if (gSetting_set_sav != SET_SAV_OFF && gScreenToDisplay == DISPLAY_MAIN) {
if (gSetting_set_sav == SET_SAV_LOGO)
UI_DisplayLogo();
else if (gSetting_set_sav == SET_SAV_MATRIX)
ScreenSaverRenderMatrix(true);
gScreenSaverDisplayed = true;
gScreenSaverMode = gSetting_set_sav;
gScreenSaverTick = 0;
gUpdateDisplay = false;
gUpdateStatus = false;
}
#endif
}
#ifdef ENABLE_FEAT_F4HWN_SLEEP
@@ -1895,6 +2049,24 @@ static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
}
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
if (gScreenSaverWakeKey != KEY_INVALID) {
if (Key == gScreenSaverWakeKey && !bKeyPressed)
gScreenSaverWakeKey = KEY_INVALID;
return;
}
if (bKeyPressed && gScreenSaverDisplayed) {
ScreenSaverExit();
BACKLIGHT_TurnOn();
if (Key != KEY_PTT) {
gScreenSaverWakeKey = Key;
gBeepToPlay = BEEP_NONE;
return;
}
}
#endif
if (Key == KEY_EXIT && !BACKLIGHT_IsOn() && gEeprom.BACKLIGHT_TIME > 0)
{ // just turn the light on for now so the user can see what's what
BACKLIGHT_TurnOn();
+1 -1
View File
@@ -31,6 +31,6 @@ uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t direction);
void APP_Update(void);
void APP_TimeSlice10ms(void);
void APP_TimeSlice500ms(void);
bool APP_IsScreenSaverDisplayed(void);
#endif
+17
View File
@@ -222,6 +222,13 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
*pMax = ARRAY_SIZE(gSubMenu_RX_TX) - 1;
break;
#if defined(ENABLE_FEAT_F4HWN) && defined(ENABLE_FEAT_F4HWN_LOGO_SAV)
case MENU_SET_SAV:
//*pMin = 0;
*pMax = SET_SAV_LEN - 1;
break;
#endif
#ifndef ENABLE_FEAT_F4HWN
#ifdef ENABLE_AM_FIX
case MENU_AM_FIX:
@@ -1030,6 +1037,11 @@ void MENU_AcceptSetting(void)
case MENU_SET_TMR:
gSetting_set_tmr = gSubMenuSelection;
break;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
case MENU_SET_SAV:
gSetting_set_sav = gSubMenuSelection;
break;
#endif
case MENU_TX_LOCK:
gTxVfo->TX_LOCK = gSubMenuSelection;
gRequestSaveChannel = 1;
@@ -1497,6 +1509,11 @@ void MENU_ShowCurrentSetting(void)
case MENU_SET_TMR:
gSubMenuSelection = gSetting_set_tmr;
break;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
case MENU_SET_SAV:
gSubMenuSelection = gSetting_set_sav;
break;
#endif
case MENU_TX_LOCK:
gSubMenuSelection = gTxVfo->TX_LOCK;
break;
+3
View File
@@ -137,6 +137,9 @@ enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
bool gSetting_set_nfm = 0;
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
uint8_t gSetting_set_sav = SET_SAV_OFF;
#endif
bool gSetting_set_tmr = 0;
bool gSetting_set_ptt_session;
#ifdef ENABLE_FEAT_F4HWN_DEBUG
+12
View File
@@ -181,6 +181,15 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
#endif
#ifdef ENABLE_FEAT_F4HWN
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
enum SET_SAV_t {
SET_SAV_OFF,
SET_SAV_LOGO,
SET_SAV_MATRIX,
SET_SAV_LEN
};
#endif
extern uint8_t gSetting_set_pwr;
extern bool gSetting_set_ptt;
extern uint8_t gSetting_set_tot;
@@ -197,6 +206,9 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
#ifdef ENABLE_FEAT_F4HWN_NARROWER
extern bool gSetting_set_nfm;
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
extern uint8_t gSetting_set_sav;
#endif
extern bool gSetting_set_tmr;
extern bool gSetting_set_ptt_session;
#ifdef ENABLE_FEAT_F4HWN_DEBUG
+17 -6
View File
@@ -454,11 +454,19 @@ gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data16[5]) ? Data16[5] : (FREQ_CHANNE
// 1FF0..0x1FF7
// TODO: address TBD
PY25Q16_ReadBuffer(0x00A158, Data, 8);
const uint8_t set_ptt_scn = Data[7] & 0x0F;
const uint8_t set_ptt_scn_sav = Data[7] & 0x0F;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
const bool set_ptt_scn_sav_valid = set_ptt_scn_sav < (SET_SAV_LEN << 2);
#else
const bool set_ptt_scn_sav_valid = 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 < 4) ? (set_ptt_scn & 0x01) : 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 < 4) ? ((set_ptt_scn & 0x02) == 0) : 1;
gSetting_set_scn = set_ptt_scn_sav_valid ? ((set_ptt_scn_sav & 0x02) == 0) : 1;
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
gSetting_set_sav = set_ptt_scn_sav_valid ? ((set_ptt_scn_sav >> 2) & 0x03) : SET_SAV_OFF;
#endif
gSetting_set_tot = (((Data[6] & 0xF0) >> 4) < 4) ? ((Data[6] & 0xF0) >> 4) : 0;
@@ -1131,13 +1139,16 @@ void SETTINGS_SaveSettings(void)
State[5] = ((tmp << 4) | (gSetting_set_ctr & 0x0F));
State[6] = ((gSetting_set_tot << 4) | (gSetting_set_eot & 0x0F));
uint8_t set_ptt_scn = gSetting_set_ptt & 0x01;
uint8_t set_ptt_scn_sav = gSetting_set_ptt & 0x01;
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
if (!gSetting_set_scn)
set_ptt_scn |= 0x02;
set_ptt_scn_sav |= 0x02;
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
set_ptt_scn_sav |= (gSetting_set_sav & 0x03) << 2;
#endif
State[7] = ((gSetting_set_pwr << 4) | set_ptt_scn);
State[7] = ((gSetting_set_pwr << 4) | set_ptt_scn_sav);
gEeprom.KEY_LOCK_PTT = gSetting_set_lck;
+18
View File
@@ -171,6 +171,9 @@ const t_menu_item MenuList[] =
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
{"SetScn", MENU_SET_SCN },
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
{"SetSav", MENU_SET_SAV },
#endif
#endif
// hidden menu items from here on
// enabled if pressing both the PTT and upper side button at power-on
@@ -298,6 +301,15 @@ const char* const gSubMenu_PONMSG[] =
"NONE"
};
#if defined(ENABLE_FEAT_F4HWN) && defined(ENABLE_FEAT_F4HWN_LOGO_SAV)
const char* const gSubMenu_SET_SAV[] =
{
"OFF",
"LOGO",
"MATRIX"
};
#endif
const char* const gSubMenu_ROGER[] =
{
"OFF",
@@ -918,6 +930,12 @@ void UI_DisplayMenu(void)
strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
break;
#if defined(ENABLE_FEAT_F4HWN) && defined(ENABLE_FEAT_F4HWN_LOGO_SAV)
case MENU_SET_SAV:
strcpy(String, gSubMenu_SET_SAV[gSubMenuSelection]);
break;
#endif
case MENU_MEM_CH:
case MENU_1_CALL:
case MENU_DEL_CH:
+7 -1
View File
@@ -163,7 +163,10 @@ enum
MENU_F2SHRT,
MENU_F2LONG,
MENU_MLONG,
MENU_BATTYP
MENU_BATTYP,
#if defined(ENABLE_FEAT_F4HWN) && defined(ENABLE_FEAT_F4HWN_LOGO_SAV)
MENU_SET_SAV
#endif
};
extern const uint8_t FIRST_HIDDEN_MENU_ITEM;
@@ -207,6 +210,9 @@ extern const char* const gSubMenu_D_RSP[4];
extern const char* const gSubMenu_SET_AUD_FM[5];
extern const char* const gSubMenu_SET_AUD_AM[3];
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
extern const char* const gSubMenu_SET_SAV[];
#endif
#endif
extern const char* const gSubMenu_PTT_ID[5];
+4
View File
@@ -16,6 +16,7 @@
#include <string.h>
#include "app/app.h"
#include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO
#include "app/fm.h"
@@ -59,6 +60,9 @@ void UI_DisplayStatus()
char str[8] = "";
gUpdateStatus = false;
if (APP_IsScreenSaverDisplayed())
return;
UI_StatusClear();
uint8_t *line = gStatusLine;
+16 -4
View File
@@ -44,6 +44,21 @@
#define LOGO_FLASH_ADDR 0x011000
#define LOGO_HEADER_SIZE 8
#define LOGO_BITMAP_ADDR (LOGO_FLASH_ADDR + LOGO_HEADER_SIZE)
static void UI_LoadLogo(void)
{
// Skip 8-byte header, then read 128x64 bitmap (1024 B):
// page 0 -> gStatusLine, pages 1..7 -> gFrameBuffer.
PY25Q16_ReadBuffer(LOGO_BITMAP_ADDR, gStatusLine, sizeof(gStatusLine));
PY25Q16_ReadBuffer(LOGO_BITMAP_ADDR + sizeof(gStatusLine), gFrameBuffer, sizeof(gFrameBuffer));
}
void UI_DisplayLogo(void)
{
UI_LoadLogo();
ST7565_BlitStatusLine();
ST7565_BlitFullScreen();
}
#endif
#ifdef ENABLE_FEAT_F4HWN_QRCODE
@@ -240,10 +255,7 @@ void UI_DisplayWelcome(void)
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO
else if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_LOGO) {
// Skip 8-byte header, then read 128x64 bitmap (1024 B):
// page 0 -> gStatusLine, pages 1..7 -> gFrameBuffer.
PY25Q16_ReadBuffer(LOGO_BITMAP_ADDR, gStatusLine, sizeof(gStatusLine));
PY25Q16_ReadBuffer(LOGO_BITMAP_ADDR + sizeof(gStatusLine), gFrameBuffer, sizeof(gFrameBuffer));
UI_LoadLogo();
}
#endif
else {
+4 -1
View File
@@ -23,6 +23,10 @@
void UI_DisplayReleaseKeys(void);
void UI_DisplayWelcome(void);
#ifdef ENABLE_FEAT_F4HWN_LOGO
void UI_DisplayLogo(void);
#endif
#ifdef ENABLE_FEAT_F4HWN_QRCODE
// Draw the embedded GitHub QR code (V4, 33x33) at (origin_x, origin_y).
// `wiki` selects the wiki URL bitmap, otherwise the repo URL bitmap.
@@ -35,4 +39,3 @@ void UI_GetMemPercents(uint16_t *flash_pct_x100, uint16_t *ram_pct_x100);
#endif
#endif