mirror of
https://github.com/armel/uv-k1-k5v3-firmware-custom.git
synced 2026-10-02 03:15:37 +00:00
Add BLTime support to overlay apps and Max preset
This commit is contained in:
1 parent
0850420fdf
commit
99057f9dd2
17 files changed
+294
-90
No files matched your search
+70
-19
@@ -234,7 +234,7 @@ static void ScreenSaverUpdateViewer(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ScreenSaverCanDisplay(void)
|
static bool ScreenSaverCanDisplay(bool modal)
|
||||||
{
|
{
|
||||||
if (gSetting_set_sav == SET_SAV_OFF ||
|
if (gSetting_set_sav == SET_SAV_OFF ||
|
||||||
gEeprom.BACKLIGHT_TIME == 0 ||
|
gEeprom.BACKLIGHT_TIME == 0 ||
|
||||||
@@ -257,7 +257,7 @@ static bool ScreenSaverCanDisplay(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gScreenToDisplay == DISPLAY_MAIN)
|
if (modal || gScreenToDisplay == DISPLAY_MAIN)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
#ifdef ENABLE_FMRADIO
|
#ifdef ENABLE_FMRADIO
|
||||||
@@ -268,9 +268,9 @@ static bool ScreenSaverCanDisplay(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ScreenSaverTryDisplay(void)
|
static void ScreenSaverTryDisplay(bool modal)
|
||||||
{
|
{
|
||||||
if (!ScreenSaverCanDisplay())
|
if (!ScreenSaverCanDisplay(modal))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (gSetting_set_sav == SET_SAV_LOGO)
|
if (gSetting_set_sav == SET_SAV_LOGO)
|
||||||
@@ -295,6 +295,28 @@ static void ScreenSaverExit(void)
|
|||||||
gUpdateStatus = true;
|
gUpdateStatus = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ScreenSaverAnimate(void)
|
||||||
|
{
|
||||||
|
if (!gScreenSaverDisplayed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (gSetting_set_sav == SET_SAV_MATRIX) {
|
||||||
|
if (++gScreenSaverTick >= 8u) {
|
||||||
|
gScreenSaverTick = 0;
|
||||||
|
ScreenSaverRenderMatrix(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (gSetting_set_sav == SET_SAV_LOGO_PLUS) {
|
||||||
|
if (++gScreenSaverTick >= 16u) {
|
||||||
|
gScreenSaverTick = 0;
|
||||||
|
ScreenSaverRenderLogoPlus(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool APP_IsScreenSaverDisplayed(void)
|
bool APP_IsScreenSaverDisplayed(void)
|
||||||
@@ -306,6 +328,47 @@ bool APP_IsScreenSaverDisplayed(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Modal foreground loops (resident tools and overlay apps) bypass APP_Update()
|
||||||
|
* and therefore also bypass the normal 10 ms fade and 500 ms BLTime service.
|
||||||
|
* Keep that service resident so every overlay app gets identical timing without
|
||||||
|
* extending the app ABI. Only selected modal screens opt into the saver; the
|
||||||
|
* others still fade from BLMax to BLMin when BLTime expires. */
|
||||||
|
void APP_ModalBacklightTick(bool allowScreenSaver)
|
||||||
|
{
|
||||||
|
if (gNextTimeslice) {
|
||||||
|
gNextTimeslice = false;
|
||||||
|
BACKLIGHT_Update();
|
||||||
|
|
||||||
|
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
|
||||||
|
if (ScreenSaverAnimate())
|
||||||
|
ScreenSaverUpdateViewer();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gNextTimeslice_500ms)
|
||||||
|
return;
|
||||||
|
gNextTimeslice_500ms = false;
|
||||||
|
|
||||||
|
if (gBacklightCountdown_500ms > 0 &&
|
||||||
|
gEeprom.BACKLIGHT_TIME < 61 &&
|
||||||
|
--gBacklightCountdown_500ms == 0)
|
||||||
|
BACKLIGHT_TurnOff();
|
||||||
|
|
||||||
|
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
|
||||||
|
if (allowScreenSaver && gBacklightCountdown_500ms == 0)
|
||||||
|
ScreenSaverTryDisplay(true);
|
||||||
|
#else
|
||||||
|
(void)allowScreenSaver;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void APP_ModalScreenSaverExit(void)
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
|
||||||
|
ScreenSaverExit();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void CheckForIncoming(void)
|
static void CheckForIncoming(void)
|
||||||
{
|
{
|
||||||
if (!g_SquelchLost)
|
if (!g_SquelchLost)
|
||||||
@@ -1667,23 +1730,11 @@ void APP_TimeSlice10ms(void)
|
|||||||
gUpdateStatus = false;
|
gUpdateStatus = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gSetting_set_sav == SET_SAV_MATRIX) {
|
if (ScreenSaverAnimate()) {
|
||||||
if (++gScreenSaverTick >= 8u) {
|
|
||||||
gScreenSaverTick = 0;
|
|
||||||
ScreenSaverRenderMatrix(false);
|
|
||||||
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
||||||
screenSaverRendered = true;
|
screenSaverRendered = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else if (gSetting_set_sav == SET_SAV_LOGO_PLUS) {
|
|
||||||
if (++gScreenSaverTick >= 16u) {
|
|
||||||
gScreenSaverTick = 0;
|
|
||||||
ScreenSaverRenderLogoPlus(false);
|
|
||||||
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
|
||||||
screenSaverRendered = true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1895,7 +1946,7 @@ void APP_TimeSlice500ms(void)
|
|||||||
) {
|
) {
|
||||||
BACKLIGHT_TurnOff();
|
BACKLIGHT_TurnOff();
|
||||||
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
|
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
|
||||||
ScreenSaverTryDisplay();
|
ScreenSaverTryDisplay(false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2101,7 +2152,7 @@ void APP_TimeSlice500ms(void)
|
|||||||
!gAskToSave &&
|
!gAskToSave &&
|
||||||
!gCssBackgroundScan)
|
!gCssBackgroundScan)
|
||||||
{
|
{
|
||||||
ScreenSaverTryDisplay();
|
ScreenSaverTryDisplay(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -32,5 +32,7 @@ void APP_Update(void);
|
|||||||
void APP_TimeSlice10ms(void);
|
void APP_TimeSlice10ms(void);
|
||||||
void APP_TimeSlice500ms(void);
|
void APP_TimeSlice500ms(void);
|
||||||
bool APP_IsScreenSaverDisplayed(void);
|
bool APP_IsScreenSaverDisplayed(void);
|
||||||
|
void APP_ModalBacklightTick(bool allowScreenSaver);
|
||||||
|
void APP_ModalScreenSaverExit(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+3
-1
@@ -63,6 +63,8 @@ enum {
|
|||||||
APP_KEY_F = 15,
|
APP_KEY_F = 15,
|
||||||
APP_KEY_PTT = 16,
|
APP_KEY_PTT = 16,
|
||||||
APP_KEY_INVALID = 19,
|
APP_KEY_INVALID = 19,
|
||||||
|
APP_KEY_SAVER = 0xFD, /* virtual: saver active, skip this app frame */
|
||||||
|
APP_KEY_WAKE = 0xFE, /* virtual: saver dismissed, redraw without action */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The framebuffer is the resident gFrameBuffer[FRAME_LINES][128]; the app draws
|
/* The framebuffer is the resident gFrameBuffer[FRAME_LINES][128]; the app draws
|
||||||
@@ -175,7 +177,7 @@ typedef struct app_api {
|
|||||||
void (*draw_battery)(void); /* UI_DrawStatusBattery into the status line */
|
void (*draw_battery)(void); /* UI_DrawStatusBattery into the status line */
|
||||||
void (*battery_sample)(void); /* periodic ADC sample so the level stays live */
|
void (*battery_sample)(void); /* periodic ADC sample so the level stays live */
|
||||||
void (*backlight_on)(void); /* BACKLIGHT_TurnOn */
|
void (*backlight_on)(void); /* BACKLIGHT_TurnOn */
|
||||||
void (*backlight_update)(void); /* BACKLIGHT_Update (fade step) */
|
void (*backlight_update)(void); /* resident fade + BLTime service */
|
||||||
void (*audio_scope)(uint8_t line, bool active); /* shared MAIN microphone scope */
|
void (*audio_scope)(uint8_t line, bool active); /* shared MAIN microphone scope */
|
||||||
|
|
||||||
uint8_t *status_line; /* -> gStatusLine (for status-bar icons) */
|
uint8_t *status_line; /* -> gStatusLine (for status-bar icons) */
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "apps/app_menu.h"
|
#include "apps/app_menu.h"
|
||||||
|
#include "app/app.h"
|
||||||
|
#include "driver/backlight.h"
|
||||||
#include "driver/st7565.h"
|
#include "driver/st7565.h"
|
||||||
#include "driver/keyboard.h"
|
#include "driver/keyboard.h"
|
||||||
#include "driver/system.h"
|
#include "driver/system.h"
|
||||||
@@ -62,6 +64,8 @@ static void app_key_hints(void)
|
|||||||
#define APP_NAME_BOX_END 102u
|
#define APP_NAME_BOX_END 102u
|
||||||
#define APP_NAME_TEXT_X 14u
|
#define APP_NAME_TEXT_X 14u
|
||||||
|
|
||||||
|
static void app_wait_release(void);
|
||||||
|
|
||||||
static void app_invert_name(uint8_t line)
|
static void app_invert_name(uint8_t line)
|
||||||
{
|
{
|
||||||
gFrameBuffer[line][APP_NAME_BOX_START] ^= 0x7Fu;
|
gFrameBuffer[line][APP_NAME_BOX_START] ^= 0x7Fu;
|
||||||
@@ -82,6 +86,24 @@ static KEY_Code_t app_get_key(void)
|
|||||||
/* APP_MenuOpen() is modal and does not return to APP_Update(). Keep
|
/* APP_MenuOpen() is modal and does not return to APP_Update(). Keep
|
||||||
* serial key injection and the viewer connection alive while waiting. */
|
* serial key injection and the viewer connection alive while waiting. */
|
||||||
K5VIEWER_ParseInput();
|
K5VIEWER_ParseInput();
|
||||||
|
#endif
|
||||||
|
APP_ModalBacklightTick(true);
|
||||||
|
|
||||||
|
if (APP_IsScreenSaverDisplayed())
|
||||||
|
{
|
||||||
|
if (KEYBOARD_GetKey() != KEY_INVALID)
|
||||||
|
{
|
||||||
|
APP_ModalScreenSaverExit();
|
||||||
|
BACKLIGHT_TurnOn();
|
||||||
|
app_wait_release();
|
||||||
|
return KEY_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYSTEM_DelayMs(10);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
||||||
K5VIEWER_Update(false);
|
K5VIEWER_Update(false);
|
||||||
#endif
|
#endif
|
||||||
KEY_Code_t key = KEYBOARD_Poll();
|
KEY_Code_t key = KEYBOARD_Poll();
|
||||||
@@ -90,8 +112,12 @@ static KEY_Code_t app_get_key(void)
|
|||||||
SYSTEM_DelayMs(30);
|
SYSTEM_DelayMs(30);
|
||||||
if (KEYBOARD_Poll() == key)
|
if (KEYBOARD_Poll() == key)
|
||||||
{
|
{
|
||||||
|
BACKLIGHT_TurnOn();
|
||||||
while (KEYBOARD_Poll() != KEY_INVALID)
|
while (KEYBOARD_Poll() != KEY_INVALID)
|
||||||
|
{
|
||||||
SYSTEM_DelayMs(10);
|
SYSTEM_DelayMs(10);
|
||||||
|
APP_ModalBacklightTick(false);
|
||||||
|
}
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,6 +135,7 @@ static void app_wait_release(void)
|
|||||||
else
|
else
|
||||||
stable = 0;
|
stable = 0;
|
||||||
SYSTEM_DelayMs(10);
|
SYSTEM_DelayMs(10);
|
||||||
|
APP_ModalBacklightTick(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,6 +215,9 @@ _Static_assert(APP_MENU_SLOT_COUNT <= APP_SLOT_COUNT,
|
|||||||
|
|
||||||
void APP_MenuOpen(void)
|
void APP_MenuOpen(void)
|
||||||
{
|
{
|
||||||
|
APP_ModalScreenSaverExit();
|
||||||
|
BACKLIGHT_TurnOn();
|
||||||
|
|
||||||
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
||||||
/* Detach the modal selector from the key state that triggered F+7. The
|
/* Detach the modal selector from the key state that triggered F+7. The
|
||||||
* normal K5Viewer updater suppresses frames while a key is held; without
|
* normal K5Viewer updater suppresses frames while a key is held; without
|
||||||
|
|||||||
+46
-3
@@ -53,6 +53,20 @@
|
|||||||
_Static_assert(sizeof(app_header_t) == 64, "app_header_t must be 64 bytes");
|
_Static_assert(sizeof(app_header_t) == 64, "app_header_t must be 64 bytes");
|
||||||
|
|
||||||
/* ---- ABI wrappers: the few resident calls that are not a direct signature match ---- */
|
/* ---- ABI wrappers: the few resident calls that are not a direct signature match ---- */
|
||||||
|
static bool app_allow_screen_saver;
|
||||||
|
static bool app_screen_saver_wake;
|
||||||
|
|
||||||
|
static void app_backlight_on(void)
|
||||||
|
{
|
||||||
|
APP_ModalScreenSaverExit();
|
||||||
|
BACKLIGHT_TurnOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void app_backlight_update(void)
|
||||||
|
{
|
||||||
|
APP_ModalBacklightTick(app_allow_screen_saver);
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t app_get_key(void)
|
static uint8_t app_get_key(void)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
||||||
@@ -60,7 +74,26 @@ static uint8_t app_get_key(void)
|
|||||||
* injection alive while an app owns the foreground loop. */
|
* injection alive while an app owns the foreground loop. */
|
||||||
K5VIEWER_ParseInput();
|
K5VIEWER_ParseInput();
|
||||||
#endif
|
#endif
|
||||||
return (uint8_t)KEYBOARD_GetKey();
|
const KEY_Code_t key = KEYBOARD_GetKey();
|
||||||
|
|
||||||
|
if (app_screen_saver_wake) {
|
||||||
|
if (key == KEY_INVALID)
|
||||||
|
app_screen_saver_wake = false;
|
||||||
|
return APP_KEY_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!APP_IsScreenSaverDisplayed())
|
||||||
|
return (uint8_t)key;
|
||||||
|
|
||||||
|
if (key == KEY_INVALID)
|
||||||
|
return APP_KEY_SAVER;
|
||||||
|
|
||||||
|
app_backlight_on();
|
||||||
|
if (key == KEY_PTT)
|
||||||
|
return APP_KEY_PTT;
|
||||||
|
|
||||||
|
app_screen_saver_wake = true;
|
||||||
|
return APP_KEY_WAKE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
||||||
@@ -72,6 +105,7 @@ static void app_blit_full(void)
|
|||||||
K5VIEWER_Update(false);
|
K5VIEWER_Update(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int8_t app_nav_dir(uint8_t key)
|
static int8_t app_nav_dir(uint8_t key)
|
||||||
{
|
{
|
||||||
int8_t direction;
|
int8_t direction;
|
||||||
@@ -749,8 +783,8 @@ static const app_api_t app_api = {
|
|||||||
.cfg_save = app_cfg_save,
|
.cfg_save = app_cfg_save,
|
||||||
.draw_battery = app_draw_battery,
|
.draw_battery = app_draw_battery,
|
||||||
.battery_sample = app_battery_sample,
|
.battery_sample = app_battery_sample,
|
||||||
.backlight_on = BACKLIGHT_TurnOn,
|
.backlight_on = app_backlight_on,
|
||||||
.backlight_update = BACKLIGHT_Update,
|
.backlight_update = app_backlight_update,
|
||||||
.audio_scope = UI_DisplayAudioScopeOverlay,
|
.audio_scope = UI_DisplayAudioScopeOverlay,
|
||||||
.status_line = gStatusLine,
|
.status_line = gStatusLine,
|
||||||
.tx_state = app_tx_state,
|
.tx_state = app_tx_state,
|
||||||
@@ -820,6 +854,11 @@ uint8_t APP_LaunchOverlay(uint8_t slot)
|
|||||||
app_fm_dirty = false;
|
app_fm_dirty = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
app_allow_screen_saver = (h.flags & APP_FLAG_SCREEN_SAVER) != 0;
|
||||||
|
app_screen_saver_wake = false;
|
||||||
|
APP_ModalScreenSaverExit();
|
||||||
|
BACKLIGHT_TurnOn();
|
||||||
|
|
||||||
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
#ifdef ENABLE_FEAT_F4HWN_K5VIEWER
|
||||||
/* The caller enters from a debounced key event, so the resident key state
|
/* The caller enters from a debounced key event, so the resident key state
|
||||||
* still contains that trigger while the modal app is running. Clear it so
|
* still contains that trigger while the modal app is running. Clear it so
|
||||||
@@ -845,6 +884,10 @@ uint8_t APP_LaunchOverlay(uint8_t slot)
|
|||||||
app_entry_t entry = (app_entry_t)(((uint32_t)ws + h.entry_off) | 1u);
|
app_entry_t entry = (app_entry_t)(((uint32_t)ws + h.entry_off) | 1u);
|
||||||
entry(&app_api);
|
entry(&app_api);
|
||||||
|
|
||||||
|
APP_ModalScreenSaverExit();
|
||||||
|
app_allow_screen_saver = false;
|
||||||
|
app_screen_saver_wake = false;
|
||||||
|
|
||||||
/* A defensive leave also covers an app returning through an error path. */
|
/* A defensive leave also covers an app returning through an error path. */
|
||||||
app_trivfo_leave();
|
app_trivfo_leave();
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,8 @@
|
|||||||
/* ---- blob header (64 bytes, little-endian; see App/apps/pack_app.py) ---- */
|
/* ---- blob header (64 bytes, little-endian; see App/apps/pack_app.py) ---- */
|
||||||
#define APP_MAGIC 0x31504146u /* "FAP1" */
|
#define APP_MAGIC 0x31504146u /* "FAP1" */
|
||||||
#define APP_HDR_VERSION 1u
|
#define APP_HDR_VERSION 1u
|
||||||
#define APP_FLAG_COMMITTED (1u << 0)
|
#define APP_FLAG_COMMITTED 0x0001u
|
||||||
|
#define APP_FLAG_SCREEN_SAVER 0x0002u
|
||||||
#define APP_NAME_LEN 16
|
#define APP_NAME_LEN 16
|
||||||
#define APP_VERSION_LEN 16
|
#define APP_VERSION_LEN 16
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ trap 'printf "\r ❌ %-13s build failed \n" "$APP_NAME"' ERR
|
|||||||
step 1 compile ; "$CC" $CFLAGS $LDFLAGS "${APP}_app.c" -lgcc -o "${APP}.elf"
|
step 1 compile ; "$CC" $CFLAGS $LDFLAGS "${APP}_app.c" -lgcc -o "${APP}.elf"
|
||||||
step 2 objcopy ; "$OBJCOPY" -O binary "${APP}.elf" "${APP}.bin"
|
step 2 objcopy ; "$OBJCOPY" -O binary "${APP}.elf" "${APP}.bin"
|
||||||
step 3 pack ; python3 ../pack_app.py "${APP}.bin" "${OUT}.app" \
|
step 3 pack ; python3 ../pack_app.py "${APP}.bin" "${OUT}.app" \
|
||||||
--name "$APP_NAME" --ver "$APP_VER" --vma "${APP_VMA}" >/dev/null
|
--name "$APP_NAME" --ver "$APP_VER" --vma "${APP_VMA}" --screensaver >/dev/null
|
||||||
trap - ERR
|
trap - ERR
|
||||||
|
|
||||||
BYTES=$(wc -c < "${APP}.bin")
|
BYTES=$(wc -c < "${APP}.bin")
|
||||||
|
|||||||
@@ -196,6 +196,50 @@ void app_main(const app_api_t *api)
|
|||||||
uint8_t prevKey = APP_KEY_INVALID;
|
uint8_t prevKey = APP_KEY_INVALID;
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
|
uint8_t key = A->get_key();
|
||||||
|
if (key == APP_KEY_SAVER) {
|
||||||
|
prevKey = APP_KEY_INVALID;
|
||||||
|
A->delay_ms(10);
|
||||||
|
A->backlight_update();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key == APP_KEY_WAKE)
|
||||||
|
key = APP_KEY_INVALID;
|
||||||
|
if (key != prevKey && key != APP_KEY_INVALID) {
|
||||||
|
A->backlight_on();
|
||||||
|
switch (key) {
|
||||||
|
case APP_KEY_EXIT:
|
||||||
|
running = false;
|
||||||
|
break;
|
||||||
|
case APP_KEY_UP:
|
||||||
|
case APP_KEY_DOWN: {
|
||||||
|
const int8_t dir = A->nav_dir(key);
|
||||||
|
if (dir > 0 && speed < 16u) speed++;
|
||||||
|
if (dir < 0 && speed > 1u) speed--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case APP_KEY_MENU:
|
||||||
|
paused = !paused;
|
||||||
|
break;
|
||||||
|
case APP_KEY_STAR:
|
||||||
|
shape = (uint8_t)((shape + 1u) % NSHAPE);
|
||||||
|
break;
|
||||||
|
case APP_KEY_F:
|
||||||
|
wire = !wire;
|
||||||
|
break;
|
||||||
|
case APP_KEY_1: case APP_KEY_2: case APP_KEY_3: case APP_KEY_4:
|
||||||
|
case APP_KEY_5: case APP_KEY_6: case APP_KEY_7: case APP_KEY_8:
|
||||||
|
if ((uint8_t)(key - APP_KEY_1) < NSHAPE)
|
||||||
|
shape = (uint8_t)(key - APP_KEY_1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prevKey = key;
|
||||||
|
if (!running)
|
||||||
|
break;
|
||||||
|
|
||||||
const shape_t *s = &SHAPES[shape];
|
const shape_t *s = &SHAPES[shape];
|
||||||
const uint8_t ia = (uint8_t)(ax >> 3), ib = (uint8_t)(ay >> 3), ic = (uint8_t)(az >> 3);
|
const uint8_t ia = (uint8_t)(ax >> 3), ib = (uint8_t)(ay >> 3), ic = (uint8_t)(az >> 3);
|
||||||
const int cx = sin8((uint8_t)(ia + 64u)), sxr = sin8(ia);
|
const int cx = sin8((uint8_t)(ia + 64u)), sxr = sin8(ia);
|
||||||
@@ -249,39 +293,6 @@ void app_main(const app_api_t *api)
|
|||||||
az += (uint16_t)((rate + 1u) / 2u);
|
az += (uint16_t)((rate + 1u) / 2u);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t key = A->get_key();
|
|
||||||
if (key != prevKey && key != APP_KEY_INVALID) {
|
|
||||||
A->backlight_on();
|
|
||||||
switch (key) {
|
|
||||||
case APP_KEY_EXIT:
|
|
||||||
running = false;
|
|
||||||
break;
|
|
||||||
case APP_KEY_UP:
|
|
||||||
case APP_KEY_DOWN: {
|
|
||||||
const int8_t dir = A->nav_dir(key);
|
|
||||||
if (dir > 0 && speed < 16u) speed++;
|
|
||||||
if (dir < 0 && speed > 1u) speed--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case APP_KEY_MENU:
|
|
||||||
paused = !paused;
|
|
||||||
break;
|
|
||||||
case APP_KEY_STAR:
|
|
||||||
shape = (uint8_t)((shape + 1u) % NSHAPE);
|
|
||||||
break;
|
|
||||||
case APP_KEY_F:
|
|
||||||
wire = !wire;
|
|
||||||
break;
|
|
||||||
case APP_KEY_1: case APP_KEY_2: case APP_KEY_3: case APP_KEY_4:
|
|
||||||
case APP_KEY_5: case APP_KEY_6: case APP_KEY_7: case APP_KEY_8:
|
|
||||||
if ((uint8_t)(key - APP_KEY_1) < NSHAPE)
|
|
||||||
shape = (uint8_t)(key - APP_KEY_1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prevKey = key;
|
|
||||||
A->backlight_update();
|
A->backlight_update();
|
||||||
A->delay_ms((uint32_t)(32u - speed * 2u)); /* slow low end, no added delay at level 16 */
|
A->delay_ms((uint32_t)(32u - speed * 2u)); /* slow low end, no added delay at level 16 */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ trap 'printf "\r ❌ %-13s build failed \n" "$APP_NAME"' ERR
|
|||||||
step 1 compile ; "$CC" $CFLAGS $LDFLAGS "${APP}_app.c" -lgcc -o "${APP}.elf"
|
step 1 compile ; "$CC" $CFLAGS $LDFLAGS "${APP}_app.c" -lgcc -o "${APP}.elf"
|
||||||
step 2 objcopy ; "$OBJCOPY" -O binary "${APP}.elf" "${APP}.bin"
|
step 2 objcopy ; "$OBJCOPY" -O binary "${APP}.elf" "${APP}.bin"
|
||||||
step 3 pack ; python3 ../pack_app.py "${APP}.bin" "${OUT}.app" \
|
step 3 pack ; python3 ../pack_app.py "${APP}.bin" "${OUT}.app" \
|
||||||
--name "$APP_NAME" --ver "$APP_VER" --vma "${APP_VMA}" >/dev/null
|
--name "$APP_NAME" --ver "$APP_VER" --vma "${APP_VMA}" --screensaver >/dev/null
|
||||||
trap - ERR
|
trap - ERR
|
||||||
|
|
||||||
BYTES=$(wc -c < "${APP}.bin")
|
BYTES=$(wc -c < "${APP}.bin")
|
||||||
|
|||||||
+17
-2
@@ -303,6 +303,7 @@ __attribute__((section(".text.entry"),used))
|
|||||||
void app_main(const app_api_t *api)
|
void app_main(const app_api_t *api)
|
||||||
{
|
{
|
||||||
A=api;
|
A=api;
|
||||||
|
A->backlight_on();
|
||||||
ch=A->fm_channels;
|
ch=A->fm_channels;
|
||||||
A->fm_state(&st,false); /* inherit the resident FM state */
|
A->fm_state(&st,false); /* inherit the resident FM state */
|
||||||
if(st.band>3) st.band=0;
|
if(st.band>3) st.band=0;
|
||||||
@@ -326,13 +327,20 @@ void app_main(const app_api_t *api)
|
|||||||
uint8_t key=A->get_key();
|
uint8_t key=A->get_key();
|
||||||
bool rep=(key==APP_KEY_UP||key==APP_KEY_DOWN);
|
bool rep=(key==APP_KEY_UP||key==APP_KEY_DOWN);
|
||||||
|
|
||||||
if(key==APP_KEY_INVALID){
|
if(key==APP_KEY_SAVER){
|
||||||
|
held=APP_KEY_INVALID; heldMs=0; firedLong=false;
|
||||||
|
A->delay_ms(10); A->backlight_update();
|
||||||
|
continue;
|
||||||
|
} else if(key==APP_KEY_WAKE||key==APP_KEY_PTT){
|
||||||
|
held=APP_KEY_INVALID; heldMs=0; firedLong=false; dirty=true;
|
||||||
|
} else if(key==APP_KEY_INVALID){
|
||||||
if(held!=APP_KEY_INVALID && !firedLong &&
|
if(held!=APP_KEY_INVALID && !firedLong &&
|
||||||
held!=APP_KEY_UP && held!=APP_KEY_DOWN){
|
held!=APP_KEY_UP && held!=APP_KEY_DOWN){
|
||||||
onShort(held); dirty=true;
|
onShort(held); dirty=true;
|
||||||
}
|
}
|
||||||
held=APP_KEY_INVALID; heldMs=0; firedLong=false;
|
held=APP_KEY_INVALID; heldMs=0; firedLong=false;
|
||||||
} else if(key!=held){
|
} else if(key!=held){
|
||||||
|
A->backlight_on();
|
||||||
held=key; heldMs=0; firedLong=false;
|
held=key; heldMs=0; firedLong=false;
|
||||||
if(rep){ onShort(key); dirty=true; } /* immediate first step */
|
if(rep){ onShort(key); dirty=true; } /* immediate first step */
|
||||||
} else {
|
} else {
|
||||||
@@ -346,13 +354,20 @@ void app_main(const app_api_t *api)
|
|||||||
|
|
||||||
/* non-blocking scan: one step each time the settle timer expires */
|
/* non-blocking scan: one step each time the settle timer expires */
|
||||||
if(scanState){
|
if(scanState){
|
||||||
|
/* Match resident FM: an active scan keeps the display awake. */
|
||||||
|
A->backlight_on();
|
||||||
if(scanTimer<=50) scanStep();
|
if(scanTimer<=50) scanStep();
|
||||||
else scanTimer=(uint16_t)(scanTimer-50);
|
else scanTimer=(uint16_t)(scanTimer-50);
|
||||||
dirty=true;
|
dirty=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dirty){ show(); dirty=false; }
|
if(dirty){ show(); dirty=false; }
|
||||||
A->delay_ms(50);
|
/* Keep the resident 10 ms fade cadence while retaining this app's
|
||||||
|
* existing 50 ms key/scan state-machine tick. */
|
||||||
|
for(uint8_t i=0;i<5u;i++){
|
||||||
|
A->delay_ms(10);
|
||||||
|
A->backlight_update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* push our state back to the resident FM and persist (config + 48 channels) */
|
/* push our state back to the resident FM and persist (config + 48 channels) */
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ MAGIC = cdefine("app_overlay.h", "APP_MAGIC").to_bytes(4, "little") #
|
|||||||
HDR_VERSION = cdefine("app_overlay.h", "APP_HDR_VERSION")
|
HDR_VERSION = cdefine("app_overlay.h", "APP_HDR_VERSION")
|
||||||
ABI_VERSION = cdefine("app_api.h", "APP_ABI_VERSION")
|
ABI_VERSION = cdefine("app_api.h", "APP_ABI_VERSION")
|
||||||
OVERLAY_MAX = cdefine("app_overlay.h", "APP_OVERLAY_MAX") # 4 KiB overlay budget
|
OVERLAY_MAX = cdefine("app_overlay.h", "APP_OVERLAY_MAX") # 4 KiB overlay budget
|
||||||
FLAG_COMMITTED = 1 # APP_FLAG_COMMITTED, bit 0
|
FLAG_COMMITTED = cdefine("app_overlay.h", "APP_FLAG_COMMITTED")
|
||||||
|
FLAG_SCREEN_SAVER = cdefine("app_overlay.h", "APP_FLAG_SCREEN_SAVER")
|
||||||
|
|
||||||
def field(s: str, n: int) -> bytes:
|
def field(s: str, n: int) -> bytes:
|
||||||
b = s.encode("ascii", "strict")[: n - 1]
|
b = s.encode("ascii", "strict")[: n - 1]
|
||||||
@@ -45,6 +46,8 @@ def main():
|
|||||||
ap.add_argument("--entry", type=lambda x: int(x, 0), default=0)
|
ap.add_argument("--entry", type=lambda x: int(x, 0), default=0)
|
||||||
ap.add_argument("--vma", type=lambda x: int(x, 0), required=True,
|
ap.add_argument("--vma", type=lambda x: int(x, 0), required=True,
|
||||||
help="RAM VMA the app was linked at (must match the firmware overlay)")
|
help="RAM VMA the app was linked at (must match the firmware overlay)")
|
||||||
|
ap.add_argument("--screensaver", action="store_true",
|
||||||
|
help="allow the resident BLTime screen saver while this app is idle")
|
||||||
a = ap.parse_args()
|
a = ap.parse_args()
|
||||||
|
|
||||||
code = open(a.infile, "rb").read()
|
code = open(a.infile, "rb").read()
|
||||||
@@ -54,10 +57,11 @@ def main():
|
|||||||
sys.exit(f"code {len(code)} B exceeds overlay budget {OVERLAY_MAX} B")
|
sys.exit(f"code {len(code)} B exceeds overlay budget {OVERLAY_MAX} B")
|
||||||
|
|
||||||
crc = zlib.crc32(code) & 0xFFFFFFFF
|
crc = zlib.crc32(code) & 0xFFFFFFFF
|
||||||
|
flags = FLAG_COMMITTED | (FLAG_SCREEN_SAVER if a.screensaver else 0)
|
||||||
header = struct.pack(
|
header = struct.pack(
|
||||||
"<4sHHIIHH16s16sI8s",
|
"<4sHHIIHH16s16sI8s",
|
||||||
MAGIC, HDR_VERSION, ABI_VERSION,
|
MAGIC, HDR_VERSION, ABI_VERSION,
|
||||||
len(code), crc, a.entry, FLAG_COMMITTED,
|
len(code), crc, a.entry, flags,
|
||||||
field(a.name, 16), field(a.ver, 16), a.vma, b"\x00" * 8,
|
field(a.name, 16), field(a.ver, 16), a.vma, b"\x00" * 8,
|
||||||
)
|
)
|
||||||
assert len(header) == 64, len(header)
|
assert len(header) == 64, len(header)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ trap 'printf "\r ❌ %-13s build failed \n" "$APP_NAME"' ERR
|
|||||||
step 1 compile ; "$CC" $CFLAGS $LDFLAGS "${APP}_app.c" -lgcc -o "${APP}.elf"
|
step 1 compile ; "$CC" $CFLAGS $LDFLAGS "${APP}_app.c" -lgcc -o "${APP}.elf"
|
||||||
step 2 objcopy ; "$OBJCOPY" -O binary "${APP}.elf" "${APP}.bin"
|
step 2 objcopy ; "$OBJCOPY" -O binary "${APP}.elf" "${APP}.bin"
|
||||||
step 3 pack ; python3 ../pack_app.py "${APP}.bin" "${OUT}.app" \
|
step 3 pack ; python3 ../pack_app.py "${APP}.bin" "${OUT}.app" \
|
||||||
--name "$APP_NAME" --ver "$APP_VER" --vma "${APP_VMA}" >/dev/null
|
--name "$APP_NAME" --ver "$APP_VER" --vma "${APP_VMA}" --screensaver >/dev/null
|
||||||
trap - ERR
|
trap - ERR
|
||||||
|
|
||||||
BYTES=$(wc -c < "${APP}.bin")
|
BYTES=$(wc -c < "${APP}.bin")
|
||||||
|
|||||||
@@ -92,6 +92,39 @@ void app_main(const app_api_t *api)
|
|||||||
prevKey = APP_KEY_INVALID;
|
prevKey = APP_KEY_INVALID;
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
|
uint8_t key = A->get_key();
|
||||||
|
if (key == APP_KEY_SAVER) {
|
||||||
|
prevKey = APP_KEY_INVALID;
|
||||||
|
A->delay_ms(10);
|
||||||
|
A->backlight_update();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key == APP_KEY_WAKE)
|
||||||
|
key = APP_KEY_INVALID;
|
||||||
|
if (key != prevKey && key != APP_KEY_INVALID) {
|
||||||
|
A->backlight_on();
|
||||||
|
switch (key) {
|
||||||
|
case APP_KEY_EXIT: running = false; break;
|
||||||
|
case APP_KEY_UP:
|
||||||
|
case APP_KEY_DOWN: {
|
||||||
|
const int8_t direction = A->nav_dir(key);
|
||||||
|
if (direction > 0 && speed < 8u) speed++;
|
||||||
|
if (direction < 0 && speed > 1u) speed--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case APP_KEY_MENU: paused = !paused; break;
|
||||||
|
case APP_KEY_STAR: bands = !bands; break;
|
||||||
|
case APP_KEY_F: autoc = !autoc; break;
|
||||||
|
case APP_KEY_1: case APP_KEY_2: case APP_KEY_3:
|
||||||
|
case APP_KEY_4: case APP_KEY_5:
|
||||||
|
var = (uint8_t)(key - APP_KEY_1); autoc = false; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prevKey = key;
|
||||||
|
if (!running)
|
||||||
|
break;
|
||||||
|
|
||||||
const uint8_t sx = VAR[var][0], sy = VAR[var][1];
|
const uint8_t sx = VAR[var][0], sy = VAR[var][1];
|
||||||
const uint8_t sd = VAR[var][2], rsh = VAR[var][3];
|
const uint8_t sd = VAR[var][2], rsh = VAR[var][3];
|
||||||
|
|
||||||
@@ -142,28 +175,6 @@ void app_main(const app_api_t *api)
|
|||||||
if (autoc && ++autoCtr >= 400u) { autoCtr = 0; var = (uint8_t)((var + 1u) % NVAR); }
|
if (autoc && ++autoCtr >= 400u) { autoCtr = 0; var = (uint8_t)((var + 1u) % NVAR); }
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t key = A->get_key();
|
|
||||||
if (key != prevKey && key != APP_KEY_INVALID) {
|
|
||||||
A->backlight_on();
|
|
||||||
switch (key) {
|
|
||||||
case APP_KEY_EXIT: running = false; break;
|
|
||||||
case APP_KEY_UP:
|
|
||||||
case APP_KEY_DOWN: {
|
|
||||||
const int8_t direction = A->nav_dir(key);
|
|
||||||
if (direction > 0 && speed < 8u) speed++;
|
|
||||||
if (direction < 0 && speed > 1u) speed--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case APP_KEY_MENU: paused = !paused; break;
|
|
||||||
case APP_KEY_STAR: bands = !bands; break;
|
|
||||||
case APP_KEY_F: autoc = !autoc; break;
|
|
||||||
case APP_KEY_1: case APP_KEY_2: case APP_KEY_3:
|
|
||||||
case APP_KEY_4: case APP_KEY_5:
|
|
||||||
var = (uint8_t)(key - APP_KEY_1); autoc = false; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prevKey = key;
|
|
||||||
A->backlight_update();
|
A->backlight_update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ LDFLAGS="-nostdlib -nostartfiles -T app.ld -Wl,--defsym,APP_VMA=${APP_VMA} -Wl,-
|
|||||||
rm -f ./*.app ./*.elf ./*.bin
|
rm -f ./*.app ./*.elf ./*.bin
|
||||||
"$CC" $CFLAGS $LDFLAGS "${APP}_app.c" -lgcc -o "${APP}.elf"
|
"$CC" $CFLAGS $LDFLAGS "${APP}_app.c" -lgcc -o "${APP}.elf"
|
||||||
"$OBJCOPY" -O binary "${APP}.elf" "${APP}.bin"
|
"$OBJCOPY" -O binary "${APP}.elf" "${APP}.bin"
|
||||||
python3 ../pack_app.py "${APP}.bin" "${OUT}.app" --name "$APP_NAME" --ver "$APP_VER" --vma "${APP_VMA}" >/dev/null
|
python3 ../pack_app.py "${APP}.bin" "${OUT}.app" --name "$APP_NAME" --ver "$APP_VER" --vma "${APP_VMA}" --screensaver >/dev/null
|
||||||
BYTES=$(wc -c < "${APP}.bin")
|
BYTES=$(wc -c < "${APP}.bin")
|
||||||
test "$BYTES" -le 4096
|
test "$BYTES" -le 4096
|
||||||
printf ' ✅ %-13s %4d B (%d%% of 4 KiB) -> %s.app\n' \
|
printf ' ✅ %-13s %4d B (%d%% of 4 KiB) -> %s.app\n' \
|
||||||
|
|||||||
@@ -205,6 +205,19 @@ void app_main(const app_api_t *api){
|
|||||||
uint8_t held=APP_KEY_INVALID, blinkTicks=0; uint16_t heldMs=0; bool longDone=false, ptt=false;
|
uint8_t held=APP_KEY_INVALID, blinkTicks=0; uint16_t heldMs=0; bool longDone=false, ptt=false;
|
||||||
while(running){
|
while(running){
|
||||||
uint8_t key=A->get_key();
|
uint8_t key=A->get_key();
|
||||||
|
if(key==APP_KEY_SAVER){
|
||||||
|
state=A->trivfo_tick();
|
||||||
|
if(state==APP_TRIVFO_RX){
|
||||||
|
A->backlight_on();
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
for(uint8_t i=0;i<TICK_MS/10u;i++){
|
||||||
|
A->delay_ms(10); A->backlight_update();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(key!=APP_KEY_INVALID&&key!=APP_KEY_WAKE) A->backlight_on();
|
||||||
|
if(key==APP_KEY_WAKE) key=APP_KEY_INVALID;
|
||||||
if(key==APP_KEY_PTT){
|
if(key==APP_KEY_PTT){
|
||||||
if(!ptt){ ptt=true; txDenied=A->trivfo_ptt(true)!=0; }
|
if(!ptt){ ptt=true; txDenied=A->trivfo_ptt(true)!=0; }
|
||||||
} else if(ptt){ ptt=false; A->trivfo_ptt(false); txDenied=false; }
|
} else if(ptt){ ptt=false; A->trivfo_ptt(false); txDenied=false; }
|
||||||
@@ -233,6 +246,8 @@ void app_main(const app_api_t *api){
|
|||||||
}
|
}
|
||||||
|
|
||||||
state=A->trivfo_tick();
|
state=A->trivfo_tick();
|
||||||
|
if(state==APP_TRIVFO_RX||state==APP_TRIVFO_TX_STATE)
|
||||||
|
A->backlight_on();
|
||||||
if(state==APP_TRIVFO_RX){
|
if(state==APP_TRIVFO_RX){
|
||||||
if(++blinkTicks>=25u){ blinkTicks=0; channelLabelOn=!channelLabelOn; }
|
if(++blinkTicks>=25u){ blinkTicks=0; channelLabelOn=!channelLabelOn; }
|
||||||
} else { blinkTicks=0; channelLabelOn=true; }
|
} else { blinkTicks=0; channelLabelOn=true; }
|
||||||
|
|||||||
@@ -186,6 +186,21 @@
|
|||||||
"EDITION_STRING": "Labs",
|
"EDITION_STRING": "Labs",
|
||||||
"TARGET": "f4hwn.labs"
|
"TARGET": "f4hwn.labs"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Max",
|
||||||
|
"inherits": "Fusion",
|
||||||
|
"cacheVariables": {
|
||||||
|
"ENABLE_FEAT_F4HWN_RESCUE_OPS": true,
|
||||||
|
"ENABLE_FEAT_F4HWN_FOXHUNT": true,
|
||||||
|
"ENABLE_FEAT_F4HWN_BEACON": true,
|
||||||
|
"ENABLE_AIRCOPY": true,
|
||||||
|
"ENABLE_FEAT_F4HWN_BEAM": true,
|
||||||
|
"ENABLE_FEAT_F4HWN_GAME": true,
|
||||||
|
"ENABLE_FEAT_F4HWN_OVERLAY_APPS": false,
|
||||||
|
"EDITION_STRING": "Max",
|
||||||
|
"TARGET": "f4hwn.max"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"buildPresets": [
|
"buildPresets": [
|
||||||
@@ -208,6 +223,10 @@
|
|||||||
{
|
{
|
||||||
"name": "Labs",
|
"name": "Labs",
|
||||||
"configurePreset": "Labs"
|
"configurePreset": "Labs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Max",
|
||||||
|
"configurePreset": "Max"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+3
-3
@@ -16,7 +16,7 @@ set -euo pipefail
|
|||||||
# ---------------------------------------------
|
# ---------------------------------------------
|
||||||
|
|
||||||
IMAGE=uvk1-uvk5v3
|
IMAGE=uvk1-uvk5v3
|
||||||
RELEASE_PRESETS=(Fusion Transfer FieldOps Labs)
|
RELEASE_PRESETS=(Fusion Transfer FieldOps Labs Max)
|
||||||
FLASH_LIMIT=$((118 * 1024))
|
FLASH_LIMIT=$((118 * 1024))
|
||||||
RAM_LIMIT=$((16 * 1024))
|
RAM_LIMIT=$((16 * 1024))
|
||||||
|
|
||||||
@@ -29,9 +29,9 @@ EXTRA_ARGS=("$@")
|
|||||||
# ---------------------------------------------
|
# ---------------------------------------------
|
||||||
# Validate preset name
|
# Validate preset name
|
||||||
# ---------------------------------------------
|
# ---------------------------------------------
|
||||||
if [[ ! "$PRESET" =~ ^(Custom|Fusion|Transfer|FieldOps|Labs|All)$ ]]; then
|
if [[ ! "$PRESET" =~ ^(Custom|Fusion|Transfer|FieldOps|Labs|Max|All)$ ]]; then
|
||||||
echo "❌ Unknown preset: '$PRESET'"
|
echo "❌ Unknown preset: '$PRESET'"
|
||||||
echo "Valid presets are: Custom, Fusion, Transfer, FieldOps, Labs, All"
|
echo "Valid presets are: Custom, Fusion, Transfer, FieldOps, Labs, Max, All"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user