mirror of
https://github.com/armel/uv-k1-k5v3-firmware-custom.git
synced 2026-10-02 03:15:37 +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
@@ -1985,10 +1985,14 @@ void APP_TimeSlice500ms(void)
|
||||
|
||||
if ((gBatteryCheckCounter & 1) == 0)
|
||||
{
|
||||
#if defined(ENABLE_FEAT_F4HWN_OVERLAY_APPS) || defined(ENABLE_FEAT_F4HWN_FOXHUNT)
|
||||
BATTERY_Sample(true);
|
||||
#else
|
||||
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryVoltageIndex++], &gBatteryCurrent);
|
||||
if (gBatteryVoltageIndex > 3)
|
||||
gBatteryVoltageIndex = 0;
|
||||
BATTERY_GetReadings(true);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-4
@@ -683,10 +683,7 @@ static void FOXHUNT_IdleHousekeeping(void)
|
||||
// hunt loop, and the beacon idle gap, never a burst), so the reading is not
|
||||
// pulled down by TX load — keeping the status icon live and letting the
|
||||
// beacon's battery gate react to a pack draining under a long run.
|
||||
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryVoltageIndex++], &gBatteryCurrent);
|
||||
if (gBatteryVoltageIndex > 3)
|
||||
gBatteryVoltageIndex = 0;
|
||||
BATTERY_GetReadings(false);
|
||||
BATTERY_Sample(false);
|
||||
|
||||
// Persist any changed setting within ~0.5 s, so it survives a power-off (not
|
||||
// just a clean EXIT). No-op when nothing changed.
|
||||
|
||||
+1
-7
@@ -40,7 +40,7 @@
|
||||
* reorder, a removal, or an append - MUST bump this. Keep in sync with the
|
||||
* value read by pack_app.py, which
|
||||
* stamps the blob the loader checks against. */
|
||||
#define APP_ABI_VERSION 4u
|
||||
#define APP_ABI_VERSION 5u
|
||||
|
||||
/* KEY codes mirrored from driver/keyboard.h (enum KEY_Code_e). Kept in sync by
|
||||
* value so the app stays independent of the firmware headers. */
|
||||
@@ -139,15 +139,10 @@ typedef struct app_api {
|
||||
/* ---- input / system ---- */
|
||||
uint8_t (*get_key)(void); /* KEYBOARD_GetKey, returns an APP_KEY_* code */
|
||||
void (*delay_ms)(uint32_t ms); /* SYSTEM_DelayMs */
|
||||
void (*backlight_tick)(void); /* BACKLIGHT_UpdateTickless */
|
||||
|
||||
/* ---- audio / indicator ---- */
|
||||
void (*play_tone)(uint16_t tone, uint16_t ms); /* full BK4819 tone burst + AF path */
|
||||
void (*led)(bool on); /* green GPIO indicator */
|
||||
|
||||
/* ---- data provided at launch ---- */
|
||||
uint32_t seed; /* resident-computed PRNG seed */
|
||||
|
||||
/* ==== appended when the ABI moved 1 -> 2; now an integral part of ABI 2.
|
||||
* A firmware and an app that agree on abi_version agree on this whole layout,
|
||||
* so these must never be reached through a table that does not include them. == */
|
||||
@@ -197,7 +192,6 @@ typedef struct app_api {
|
||||
void (*fm_enter)(uint16_t freq, uint8_t band); /* BK1080_Init + antenna filter + audio on */
|
||||
void (*fm_exit)(void); /* audio off + BK1080_Init0 + restore filter */
|
||||
void (*fm_set_freq)(uint16_t freq, uint8_t band);/* BK1080_SetFrequency (freq in 0.1 MHz) */
|
||||
uint16_t (*fm_read)(uint8_t reg); /* BK1080_ReadRegister (RSSI / valid) */
|
||||
uint16_t (*fm_lo)(uint8_t band); /* band low limit (0.1 MHz) */
|
||||
uint16_t (*fm_hi)(uint8_t band); /* band high limit (0.1 MHz) */
|
||||
void (*fm_mute)(bool mute); /* BK1080_Mute */
|
||||
|
||||
+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();
|
||||
|
||||
@@ -91,7 +91,10 @@ static bool settingKey(uint8_t key,int8_t dir){
|
||||
switch(key){
|
||||
case APP_KEY_1: beaconTx =rangeStep(beaconTx, TX_MIN, TX_MAX, TX_STEP, dir); return true;
|
||||
case APP_KEY_2: beaconIdle=rangeStep(beaconIdle,IDLE_MIN,IDLE_MAX,IDLE_STEP,dir); return true;
|
||||
case APP_KEY_3: foxFox=(uint8_t)((foxFox+(dir>0?1:FOX_COUNT-1))%FOX_COUNT); return true;
|
||||
case APP_KEY_3:
|
||||
if(dir>0){ if(++foxFox>=FOX_COUNT) foxFox=0; }
|
||||
else foxFox=foxFox?(uint8_t)(foxFox-1u):(uint8_t)(FOX_COUNT-1u);
|
||||
return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,9 +242,12 @@ void app_main(const app_api_t *api) {
|
||||
kbdPrev = APP_KEY_INVALID; kbdCur = APP_KEY_INVALID;
|
||||
uint8_t swap = 0;
|
||||
|
||||
srand_custom(api->seed);
|
||||
/* The low BK4819 counter bits vary continuously; mix them with the tuned
|
||||
* frequency instead of carrying a launch-only seed field in every ABI
|
||||
* table. */
|
||||
srand_custom(((uint32_t)A->bk_read(0x67u) << 16) ^ A->rx_freq());
|
||||
A->led(false);
|
||||
A->backlight_tick();
|
||||
A->backlight_on();
|
||||
|
||||
A->display_clear();
|
||||
reset(); initWall(); initRacket(); initBall();
|
||||
|
||||
@@ -238,7 +238,11 @@ static void menu(void)
|
||||
static void upDown(int8_t step)
|
||||
{
|
||||
if(scanState){ scanState=step; scanTuneNext(); return; } /* continue scan, new direction */
|
||||
if(askSave){ savePos=(uint8_t)((savePos+step+CHMAX)%CHMAX); return; }
|
||||
if(askSave){
|
||||
if(step>0){ if(++savePos>=CHMAX) savePos=0; }
|
||||
else savePos=savePos?(uint8_t)(savePos-1u):(uint8_t)(CHMAX-1u);
|
||||
return;
|
||||
}
|
||||
if(st.is_mr){
|
||||
uint8_t c=findNext((uint8_t)(st.sel_ch+step),step);
|
||||
if(c!=0xFF && c!=st.sel_ch){ st.sel_ch=c; st.freq_playing=ch[c]; tune(); }
|
||||
|
||||
@@ -80,7 +80,10 @@ static void drawMeter(const app_trivfo_info_t *v){
|
||||
int16_t dbm=v->rssi_dbm; if(dbm>-53)dbm=-53;
|
||||
uint8_t s=0,over=0;
|
||||
if(dbm>=-93){ s=9; over=(uint8_t)(dbm+93); if(over>40)over=40; }
|
||||
else if(dbm>=-141) s=(uint8_t)((dbm+147)/6);
|
||||
/* dbm + 147 is non-negative in this branch. Keep the division unsigned:
|
||||
* otherwise GCC pulls the ~460-byte signed division helper into the 4 KiB
|
||||
* overlay even though no signed quotient is required. */
|
||||
else if(dbm>=-141) s=(uint8_t)((uint16_t)(dbm+147)/6u);
|
||||
|
||||
char *o=text; if(dbm>-100)*o++=' '; o=puti(o,dbm); o=put(o," dBm"); *o='\0';
|
||||
A->print_tiny(text,2,1,false,true);
|
||||
|
||||
@@ -790,7 +790,7 @@ _Static_assert(offsetof(mb_state_t, firmware_slot) == 16u,
|
||||
_Static_assert(offsetof(mb_state_t, state_crc32) == 20u,
|
||||
"state CRC must cover the first 20 bytes (magic..bank_inv)");
|
||||
|
||||
static uint32_t mb_crc32_bytes(const uint8_t *p, uint32_t len)
|
||||
uint32_t MB_Crc32Bytes(const uint8_t *p, uint32_t len)
|
||||
{
|
||||
uint32_t crc = 0xFFFFFFFFu;
|
||||
|
||||
@@ -848,7 +848,7 @@ static mb_mark_status_t mb_read_state_copy(uint32_t base, mb_state_t *st)
|
||||
return MB_MARK_CORRUPT;
|
||||
if (st->image_size == 0u || st->image_size > MB_INT_APP_SIZE)
|
||||
return MB_MARK_CORRUPT;
|
||||
if (mb_crc32_bytes((const uint8_t *)st,
|
||||
if (MB_Crc32Bytes((const uint8_t *)st,
|
||||
sizeof(*st) - sizeof(st->state_crc32)) != st->state_crc32)
|
||||
return MB_MARK_CORRUPT;
|
||||
|
||||
@@ -857,7 +857,7 @@ static mb_mark_status_t mb_read_state_copy(uint32_t base, mb_state_t *st)
|
||||
st->slot_inv = (uint8_t)~legacy_index;
|
||||
st->config_bank = legacy_index;
|
||||
st->bank_inv = (uint8_t)~legacy_index;
|
||||
st->state_crc32 = mb_crc32_bytes((const uint8_t *)st,
|
||||
st->state_crc32 = MB_Crc32Bytes((const uint8_t *)st,
|
||||
sizeof(*st) - sizeof(st->state_crc32));
|
||||
return MB_MARK_VALID;
|
||||
}
|
||||
@@ -871,7 +871,7 @@ static mb_mark_status_t mb_read_state_copy(uint32_t base, mb_state_t *st)
|
||||
if (st->config_bank >= MB_BANK_COUNT) return MB_MARK_CORRUPT;
|
||||
if (st->image_size == 0u ||
|
||||
st->image_size > MB_INT_APP_SIZE) return MB_MARK_CORRUPT;
|
||||
if (mb_crc32_bytes((const uint8_t *)st,
|
||||
if (MB_Crc32Bytes((const uint8_t *)st,
|
||||
sizeof(*st) - sizeof(st->state_crc32)) != st->state_crc32)
|
||||
return MB_MARK_CORRUPT;
|
||||
return MB_MARK_VALID;
|
||||
@@ -965,7 +965,7 @@ static uint8_t mb_commit_state(mb_state_t *st,
|
||||
st->generation = (current_status == MB_MARK_VALID) ? current->generation + 1u : 0u;
|
||||
st->slot_inv = (uint8_t)~st->firmware_slot;
|
||||
st->bank_inv = (uint8_t)~st->config_bank;
|
||||
st->state_crc32 = mb_crc32_bytes((const uint8_t *)st,
|
||||
st->state_crc32 = MB_Crc32Bytes((const uint8_t *)st,
|
||||
sizeof(*st) - sizeof(st->state_crc32));
|
||||
|
||||
const uint32_t target_base = ((current_status == MB_MARK_VALID ||
|
||||
@@ -1089,7 +1089,7 @@ static void mb_copy_str(char *dst, uint8_t cap, const char *src)
|
||||
static uint32_t mb_int_image_crc32(uint32_t len)
|
||||
{
|
||||
const uint8_t *p = (const uint8_t *)MB_INT_APP_BASE;
|
||||
return mb_crc32_bytes(p, len);
|
||||
return MB_Crc32Bytes(p, len);
|
||||
}
|
||||
|
||||
static bool mb_internal_matches(uint32_t image_size, uint32_t image_crc32)
|
||||
|
||||
@@ -84,6 +84,11 @@ enum {
|
||||
MB_ERR_RAM_LOAD /* restore stub RAM copy mismatch */
|
||||
};
|
||||
|
||||
/* CRC-32 (zlib) over a resident memory buffer. Multiboot and overlay apps
|
||||
* share this implementation; keeping it here avoids carrying two identical
|
||||
* bitwise CRC loops in the MCU flash. */
|
||||
uint32_t MB_Crc32Bytes(const uint8_t *data, uint32_t len);
|
||||
|
||||
/* Multi-slot API used by the boot selector. Validation always covers the full
|
||||
* image CRC before restore. progress_line may point to a 128-byte LCD page; the
|
||||
* RAM copier then fills it while reflashing. Pass NULL to disable LCD updates.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "battery.h"
|
||||
#include "board.h"
|
||||
#include "driver/backlight.h"
|
||||
#include "driver/st7565.h"
|
||||
#include "functions.h"
|
||||
@@ -129,6 +130,16 @@ unsigned int BATTERY_VoltsToPercent(const unsigned int voltage_10mV)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_FEAT_F4HWN_OVERLAY_APPS) || defined(ENABLE_FEAT_F4HWN_FOXHUNT)
|
||||
void BATTERY_Sample(const bool bDisplayBatteryLevel)
|
||||
{
|
||||
BOARD_ADC_GetBatteryInfo(&gBatteryVoltages[gBatteryVoltageIndex++], &gBatteryCurrent);
|
||||
if (gBatteryVoltageIndex > 3u)
|
||||
gBatteryVoltageIndex = 0u;
|
||||
BATTERY_GetReadings(bDisplayBatteryLevel);
|
||||
}
|
||||
#endif
|
||||
|
||||
void BATTERY_GetReadings(const bool bDisplayBatteryLevel)
|
||||
{
|
||||
const uint8_t PreviousBatteryLevel = gBatteryDisplayLevel;
|
||||
|
||||
@@ -45,6 +45,9 @@ typedef enum {
|
||||
|
||||
|
||||
unsigned int BATTERY_VoltsToPercent(unsigned int voltage_10mV);
|
||||
#if defined(ENABLE_FEAT_F4HWN_OVERLAY_APPS) || defined(ENABLE_FEAT_F4HWN_FOXHUNT)
|
||||
void BATTERY_Sample(bool bDisplayBatteryLevel);
|
||||
#endif
|
||||
void BATTERY_GetReadings(bool bDisplayBatteryLevel);
|
||||
void BATTERY_TimeSlice500ms(void);
|
||||
|
||||
|
||||
+2
-2
@@ -402,12 +402,12 @@ void UI_DisplayPopup(const char *string)
|
||||
UI_PrintStringSmallNormal("Press EXIT", 9, 118, 6);
|
||||
}
|
||||
|
||||
void UI_DisplayClear()
|
||||
void UI_DisplayClear(void)
|
||||
{
|
||||
memset(gFrameBuffer, 0, sizeof(gFrameBuffer));
|
||||
}
|
||||
|
||||
void UI_StatusClear()
|
||||
void UI_StatusClear(void)
|
||||
{
|
||||
memset(gStatusLine, 0, sizeof(gStatusLine));
|
||||
}
|
||||
+2
-2
@@ -44,7 +44,7 @@ void UI_DrawPixelBuffer(uint8_t (*buffer)[128], uint8_t x, uint8_t y, bool black
|
||||
void UI_DrawLineBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);
|
||||
void UI_DrawRectangleBuffer(uint8_t (*buffer)[128], int16_t x1, int16_t y1, int16_t x2, int16_t y2, bool black);
|
||||
|
||||
void UI_DisplayClear();
|
||||
void UI_StatusClear();
|
||||
void UI_DisplayClear(void);
|
||||
void UI_StatusClear(void);
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user