mirror of
https://github.com/armel/uv-k1-k5v3-firmware-custom.git
synced 2026-10-02 11:08:20 +00:00
Optimize overlay ABI and reduce flash footprint
This commit is contained in:
1 parent
8c78d28f0d
commit
88e76b0e9b
14 files changed
+126
-126
No files matched your search
+73
-100
@@ -28,6 +28,7 @@
|
||||
#include "app/fm.h"
|
||||
#endif
|
||||
#include "driver/keyboard.h"
|
||||
#include "driver/mb_flash.h"
|
||||
#include "driver/py25q16.h"
|
||||
#include "driver/st7565.h"
|
||||
#include "driver/system.h"
|
||||
@@ -47,22 +48,7 @@
|
||||
|
||||
_Static_assert(sizeof(app_header_t) == 64, "app_header_t must be 64 bytes");
|
||||
|
||||
/* CRC-32 (zlib) over RAM bytes - matches App/apps/pack_app.py and the firmware's
|
||||
* mb_ext_image_crc32 (init 0xFFFFFFFF, poly 0xEDB88320, final XOR). */
|
||||
static uint32_t app_crc32(const uint8_t *p, uint32_t len)
|
||||
{
|
||||
uint32_t crc = 0xFFFFFFFFu;
|
||||
while (len--) {
|
||||
crc ^= *p++;
|
||||
for (int k = 0; k < 8; k++)
|
||||
crc = (crc >> 1) ^ (0xEDB88320u & (0u - (crc & 1u)));
|
||||
}
|
||||
return crc ^ 0xFFFFFFFFu;
|
||||
}
|
||||
|
||||
/* ---- ABI wrappers: the few resident calls that are not a direct signature match ---- */
|
||||
static void app_display_clear(void) { UI_DisplayClear(); }
|
||||
static void app_status_clear(void) { UI_StatusClear(); }
|
||||
static uint8_t app_get_key(void) { return (uint8_t)KEYBOARD_GetKey(); }
|
||||
static int8_t app_nav_dir(uint8_t key)
|
||||
{
|
||||
@@ -87,14 +73,6 @@ static void app_play_tone(uint16_t tone, uint16_t ms)
|
||||
AUDIO_AudioPathOff();
|
||||
}
|
||||
|
||||
static uint32_t app_make_seed(void)
|
||||
{
|
||||
/* Reproduces the original Breakout seed source. */
|
||||
return BK4819_ReadRegister(BK4819_REG_67) & 0x01FF
|
||||
* gBatteryVoltageAverage
|
||||
* gEeprom.VfoInfo[0].pRX->Frequency;
|
||||
}
|
||||
|
||||
/* ---- ABI 4: resident triple-VFO engine ---------------------------------
|
||||
* The overlay owns the UI and key timing, while this resident engine owns all
|
||||
* radio details. Keeping VFO_Info_t and BK4819 sequencing on this side makes
|
||||
@@ -519,10 +497,7 @@ static void app_battery_sample(void)
|
||||
if (app_trivfo_transmitting)
|
||||
return;
|
||||
|
||||
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryVoltageIndex++], &gBatteryCurrent);
|
||||
if (gBatteryVoltageIndex > 3)
|
||||
gBatteryVoltageIndex = 0;
|
||||
BATTERY_GetReadings(false);
|
||||
BATTERY_Sample(false);
|
||||
}
|
||||
|
||||
/* ---- v2 TX (beacon) ---- */
|
||||
@@ -569,7 +544,6 @@ static void app_fm_exit(void)
|
||||
BK4819_PickRXFilterPathBasedOnFrequency(gRxVfo->pRX->Frequency); /* restore RX filter */
|
||||
}
|
||||
static void app_fm_set_freq(uint16_t f, uint8_t b) { BK1080_SetFrequency(f, b); }
|
||||
static uint16_t app_fm_read(uint8_t r) { return BK1080_ReadRegister((BK1080_Register_t)r); }
|
||||
static uint16_t app_fm_lo(uint8_t b) { return BK1080_GetFreqLoLimit(b); }
|
||||
static uint16_t app_fm_hi(uint8_t b) { return BK1080_GetFreqHiLimit(b); }
|
||||
static void app_fm_mute(bool m) { BK1080_Mute(m); }
|
||||
@@ -628,6 +602,75 @@ uint8_t APP_SlotInfo(uint8_t slot, app_header_t *out_header)
|
||||
return (h.magic == APP_MAGIC) ? APP_OK : APP_ERR_MAGIC;
|
||||
}
|
||||
|
||||
/* All services are immutable. Keeping the table in flash avoids rebuilding a
|
||||
* roughly quarter-kilobyte automatic object on every launch and removes that
|
||||
* object from the launcher's stack frame. */
|
||||
static const app_api_t app_api = {
|
||||
.abi_version = APP_ABI_VERSION,
|
||||
.fb = gFrameBuffer,
|
||||
.display_clear = UI_DisplayClear,
|
||||
.status_clear = UI_StatusClear,
|
||||
.draw_line = UI_DrawLineBuffer,
|
||||
.draw_rect = UI_DrawRectangleBuffer,
|
||||
.print_bold = UI_PrintStringSmallBold,
|
||||
.print_tiny = GUI_DisplaySmallest,
|
||||
.blit_full = ST7565_BlitFullScreen,
|
||||
.blit_line = ST7565_BlitLine,
|
||||
.blit_status = ST7565_BlitStatusLine,
|
||||
.get_key = app_get_key,
|
||||
.delay_ms = SYSTEM_DelayMs,
|
||||
.play_tone = app_play_tone,
|
||||
.led = app_led,
|
||||
.print_normal = UI_PrintStringSmallNormal,
|
||||
.print_inverse = GUI_DisplaySmallestInverse,
|
||||
.display_freq = UI_DisplayFrequency,
|
||||
.rssi_dbm = app_rssi_dbm,
|
||||
.bk_read = app_bk_read,
|
||||
.bk_write = app_bk_write,
|
||||
.set_agc = BK4819_SetAGC,
|
||||
.set_af = app_set_af,
|
||||
.audio_path = app_audio_path,
|
||||
.prepare_tone = app_prepare_tone,
|
||||
.play_tone_raw = app_play_tone_raw,
|
||||
.tones_off_rx = app_tones_off_rx,
|
||||
.rx_freq = app_rx_freq,
|
||||
.cfg_load = app_cfg_load,
|
||||
.cfg_save = app_cfg_save,
|
||||
.draw_battery = app_draw_battery,
|
||||
.battery_sample = app_battery_sample,
|
||||
.backlight_on = BACKLIGHT_TurnOn,
|
||||
.backlight_update = BACKLIGHT_Update,
|
||||
.status_line = gStatusLine,
|
||||
.tx_state = app_tx_state,
|
||||
.tx_set_params = app_tx_set_params,
|
||||
.tx_tone = app_tx_tone,
|
||||
.tx_mute = app_tx_mute,
|
||||
.tx_end = app_tx_end,
|
||||
.tx_freq = app_tx_freq,
|
||||
.boot_callsign = app_boot_callsign,
|
||||
.print_string = UI_PrintString,
|
||||
#ifdef ENABLE_FMRADIO
|
||||
.fm_enter = app_fm_enter,
|
||||
.fm_exit = app_fm_exit,
|
||||
.fm_set_freq = app_fm_set_freq,
|
||||
.fm_lo = app_fm_lo,
|
||||
.fm_hi = app_fm_hi,
|
||||
.fm_mute = app_fm_mute,
|
||||
.fm_valid = app_fm_valid,
|
||||
.fm_channels = gFM_Channels,
|
||||
.fm_state = app_fm_state,
|
||||
.fm_commit = app_fm_commit,
|
||||
#endif
|
||||
.nav_dir = app_nav_dir,
|
||||
.trivfo_enter = app_trivfo_enter,
|
||||
.trivfo_leave = app_trivfo_leave,
|
||||
.trivfo_get = app_trivfo_get,
|
||||
.trivfo_select = app_trivfo_select,
|
||||
.trivfo_step = app_trivfo_step,
|
||||
.trivfo_tick = app_trivfo_tick,
|
||||
.trivfo_ptt = app_trivfo_ptt,
|
||||
};
|
||||
|
||||
uint8_t APP_LaunchOverlay(uint8_t slot)
|
||||
{
|
||||
app_header_t h;
|
||||
@@ -650,7 +693,7 @@ uint8_t APP_LaunchOverlay(uint8_t slot)
|
||||
memset(ws, 0, APP_OVERLAY_MAX);
|
||||
PY25Q16_ReadBuffer(APP_SLOT_BASE(slot) + APP_CODE_OFFSET, ws, h.code_size);
|
||||
|
||||
if (app_crc32(ws, h.code_size) != h.code_crc32) {
|
||||
if (MB_Crc32Bytes(ws, h.code_size) != h.code_crc32) {
|
||||
PY25Q16_InvalidateCache();
|
||||
return APP_ERR_CRC;
|
||||
}
|
||||
@@ -659,76 +702,6 @@ uint8_t APP_LaunchOverlay(uint8_t slot)
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
const app_api_t api = {
|
||||
.abi_version = APP_ABI_VERSION,
|
||||
.fb = gFrameBuffer,
|
||||
.display_clear = app_display_clear,
|
||||
.status_clear = app_status_clear,
|
||||
.draw_line = UI_DrawLineBuffer,
|
||||
.draw_rect = UI_DrawRectangleBuffer,
|
||||
.print_bold = UI_PrintStringSmallBold,
|
||||
.print_tiny = GUI_DisplaySmallest,
|
||||
.blit_full = ST7565_BlitFullScreen,
|
||||
.blit_line = ST7565_BlitLine,
|
||||
.blit_status = ST7565_BlitStatusLine,
|
||||
.get_key = app_get_key,
|
||||
.delay_ms = SYSTEM_DelayMs,
|
||||
.backlight_tick = BACKLIGHT_UpdateTickless,
|
||||
.play_tone = app_play_tone,
|
||||
.led = app_led,
|
||||
.seed = app_make_seed(),
|
||||
/* v2 */
|
||||
.print_normal = UI_PrintStringSmallNormal,
|
||||
.print_inverse = GUI_DisplaySmallestInverse,
|
||||
.display_freq = UI_DisplayFrequency,
|
||||
.rssi_dbm = app_rssi_dbm,
|
||||
.bk_read = app_bk_read,
|
||||
.bk_write = app_bk_write,
|
||||
.set_agc = BK4819_SetAGC,
|
||||
.set_af = app_set_af,
|
||||
.audio_path = app_audio_path,
|
||||
.prepare_tone = app_prepare_tone,
|
||||
.play_tone_raw = app_play_tone_raw,
|
||||
.tones_off_rx = app_tones_off_rx,
|
||||
.rx_freq = app_rx_freq,
|
||||
.cfg_load = app_cfg_load,
|
||||
.cfg_save = app_cfg_save,
|
||||
.draw_battery = app_draw_battery,
|
||||
.battery_sample = app_battery_sample,
|
||||
.backlight_on = BACKLIGHT_TurnOn,
|
||||
.backlight_update = BACKLIGHT_Update,
|
||||
.status_line = gStatusLine,
|
||||
.tx_state = app_tx_state,
|
||||
.tx_set_params = app_tx_set_params,
|
||||
.tx_tone = app_tx_tone,
|
||||
.tx_mute = app_tx_mute,
|
||||
.tx_end = app_tx_end,
|
||||
.tx_freq = app_tx_freq,
|
||||
.boot_callsign = app_boot_callsign,
|
||||
.print_string = UI_PrintString,
|
||||
#ifdef ENABLE_FMRADIO
|
||||
.fm_enter = app_fm_enter,
|
||||
.fm_exit = app_fm_exit,
|
||||
.fm_set_freq = app_fm_set_freq,
|
||||
.fm_read = app_fm_read,
|
||||
.fm_lo = app_fm_lo,
|
||||
.fm_hi = app_fm_hi,
|
||||
.fm_mute = app_fm_mute,
|
||||
.fm_valid = app_fm_valid,
|
||||
.fm_channels = gFM_Channels,
|
||||
.fm_state = app_fm_state,
|
||||
.fm_commit = app_fm_commit,
|
||||
#endif
|
||||
.nav_dir = app_nav_dir,
|
||||
.trivfo_enter = app_trivfo_enter,
|
||||
.trivfo_leave = app_trivfo_leave,
|
||||
.trivfo_get = app_trivfo_get,
|
||||
.trivfo_select = app_trivfo_select,
|
||||
.trivfo_step = app_trivfo_step,
|
||||
.trivfo_tick = app_trivfo_tick,
|
||||
.trivfo_ptt = app_trivfo_ptt,
|
||||
};
|
||||
|
||||
app_run_slot = slot; /* for cfg_load / cfg_save */
|
||||
app_cfg_len = 0;
|
||||
#ifdef ENABLE_FMRADIO
|
||||
@@ -750,7 +723,7 @@ uint8_t APP_LaunchOverlay(uint8_t slot)
|
||||
RADIO_SetupRegisters(true);
|
||||
|
||||
app_entry_t entry = (app_entry_t)(((uint32_t)ws + h.entry_off) | 1u);
|
||||
entry(&api);
|
||||
entry(&app_api);
|
||||
|
||||
/* A defensive leave also covers an app returning through an error path. */
|
||||
app_trivfo_leave();
|
||||
|
||||
Reference in new issue
Block a user