diff --git a/App/app/app.c b/App/app/app.c index 653be3ff..28282d8e 100644 --- a/App/app/app.c +++ b/App/app/app.c @@ -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 } } diff --git a/App/app/foxhunt.c b/App/app/foxhunt.c index 34099575..20e7be20 100644 --- a/App/app/foxhunt.c +++ b/App/app/foxhunt.c @@ -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. diff --git a/App/apps/app_api.h b/App/apps/app_api.h index 5396f48c..e78f41b7 100644 --- a/App/apps/app_api.h +++ b/App/apps/app_api.h @@ -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 */ diff --git a/App/apps/app_overlay.c b/App/apps/app_overlay.c index 15fff980..9270097d 100644 --- a/App/apps/app_overlay.c +++ b/App/apps/app_overlay.c @@ -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(); diff --git a/App/apps/beacon/beacon_app.c b/App/apps/beacon/beacon_app.c index c9b59cea..0228c980 100644 --- a/App/apps/beacon/beacon_app.c +++ b/App/apps/beacon/beacon_app.c @@ -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; } } diff --git a/App/apps/breakout/breakout_app.c b/App/apps/breakout/breakout_app.c index 493cca86..c85bb99b 100644 --- a/App/apps/breakout/breakout_app.c +++ b/App/apps/breakout/breakout_app.c @@ -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(); diff --git a/App/apps/fm/fm_app.c b/App/apps/fm/fm_app.c index 85520bec..dac7aa08 100644 --- a/App/apps/fm/fm_app.c +++ b/App/apps/fm/fm_app.c @@ -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(); } diff --git a/App/apps/trivfo/trivfo_app.c b/App/apps/trivfo/trivfo_app.c index 20b8dd78..f4fe1896 100644 --- a/App/apps/trivfo/trivfo_app.c +++ b/App/apps/trivfo/trivfo_app.c @@ -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); diff --git a/App/driver/mb_flash.c b/App/driver/mb_flash.c index 9b97a1c1..05fd6a5f 100644 --- a/App/driver/mb_flash.c +++ b/App/driver/mb_flash.c @@ -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) diff --git a/App/driver/mb_flash.h b/App/driver/mb_flash.h index 4c8e1215..14b3bdf3 100644 --- a/App/driver/mb_flash.h +++ b/App/driver/mb_flash.h @@ -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. diff --git a/App/helper/battery.c b/App/helper/battery.c index c02a1814..d3fd2fa9 100644 --- a/App/helper/battery.c +++ b/App/helper/battery.c @@ -17,6 +17,7 @@ #include #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; diff --git a/App/helper/battery.h b/App/helper/battery.h index eb7515a8..6b290ab5 100644 --- a/App/helper/battery.h +++ b/App/helper/battery.h @@ -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); diff --git a/App/ui/helper.c b/App/ui/helper.c index f25f9622..ca4392b2 100644 --- a/App/ui/helper.c +++ b/App/ui/helper.c @@ -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)); } diff --git a/App/ui/helper.h b/App/ui/helper.h index 1d2a32a7..5dc4ecea 100644 --- a/App/ui/helper.h +++ b/App/ui/helper.h @@ -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