UA1ZBE Custom Firmware v1.0
Features: - VFO mode with direct frequency input - POCSAG decoder (512/1200 baud) with BCH(31,21) correction - Full-screen Spectrum analyzer - FM Radio receiver - RSSI signal indicator overlay - Custom boot splash (UA1ZBE / POCSAG pager / build date) Architecture: - app/mode.c — mode dispatcher (VFO/POCSAG/Spectrum/FM) - app/boot_splash.c — 2-second boot splash - app/pocsag/ — POCSAG decoder + BCH correction - app/display_rssi.c — RSSI indicator - main.c — entry point with custom init - syscalls.c — bare-metal _sbrk stub Build: arm-none-eabi-gcc -Os -flto -Wall -Werror -Wextra Size: 57.9KB Flash / 3.6KB RAM Controls: - 0-9: Direct frequency input (VFO) - SK2: POCSAG mode - SK1: Spectrum analyzer - 0: FM Radio - EXIT: Return to VFO - F/*: Toggle 512/1200 baud (in POCSAG)
This commit is contained in:
128
app/display_rssi.c
Normal file
128
app/display_rssi.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/* UA1ZBE Custom Firmware - RSSI Display Implementation
|
||||
*
|
||||
* Reads RSSI from BK4819 REG_67 (9-bit value).
|
||||
* Conversion: dBm = (raw / 2) - 160 + band_correction
|
||||
*
|
||||
* Displays as "S:XX" format with optional mini bar.
|
||||
* Updates every ~150ms via internal counter.
|
||||
*/
|
||||
|
||||
#include "display_rssi.h"
|
||||
#include "driver/bk4819.h"
|
||||
#include "driver/st7565.h"
|
||||
#include "ui/helper.h"
|
||||
#include "ui/main.h"
|
||||
#include "misc.h"
|
||||
#include "radio.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* dBm correction table — defined in ui/main.c */
|
||||
extern const int8_t dBmCorrTable[7];
|
||||
|
||||
/* === Internal state === */
|
||||
|
||||
static int16_t s_rssi_dbm;
|
||||
static uint16_t s_rssi_raw;
|
||||
static uint8_t s_s_level;
|
||||
static uint16_t s_update_counter;
|
||||
|
||||
/* Update interval: ~15 (150ms at 10ms tick) */
|
||||
#define RSSI_UPDATE_INTERVAL 15
|
||||
|
||||
/* S-meter thresholds (dBm) — simplified from U8RssiMap */
|
||||
static const int8_t s_thresholds[] = {
|
||||
-121, -115, -109, -103, -97, -91, -85, -79, -73, -63
|
||||
};
|
||||
|
||||
void RSSI_Init(void)
|
||||
{
|
||||
s_rssi_dbm = -160;
|
||||
s_rssi_raw = 0;
|
||||
s_s_level = 0;
|
||||
s_update_counter = 0;
|
||||
}
|
||||
|
||||
void RSSI_Update(void)
|
||||
{
|
||||
s_update_counter++;
|
||||
if (s_update_counter < RSSI_UPDATE_INTERVAL)
|
||||
return;
|
||||
s_update_counter = 0;
|
||||
|
||||
/* Read raw RSSI from BK4819 */
|
||||
s_rssi_raw = BK4819_GetRSSI();
|
||||
|
||||
/* Convert to dBm: (raw / 2) - 160 + band_correction
|
||||
* Avoid division: raw >> 1 */
|
||||
int8_t band_corr = dBmCorrTable[gRxVfo->Band];
|
||||
s_rssi_dbm = (int16_t)(s_rssi_raw >> 1) - 160 + band_corr;
|
||||
|
||||
/* Calculate S-level */
|
||||
s_s_level = 0;
|
||||
for (uint8_t i = 0; i < ARRAY_SIZE(s_thresholds); i++) {
|
||||
if (s_rssi_dbm >= s_thresholds[i]) {
|
||||
s_s_level = i + 1;
|
||||
}
|
||||
}
|
||||
if (s_s_level > 9)
|
||||
s_s_level = 9;
|
||||
}
|
||||
|
||||
int16_t RSSI_GetdBm(void)
|
||||
{
|
||||
return s_rssi_dbm;
|
||||
}
|
||||
|
||||
uint16_t RSSI_GetRaw(void)
|
||||
{
|
||||
return s_rssi_raw;
|
||||
}
|
||||
|
||||
uint8_t RSSI_GetSLevel(void)
|
||||
{
|
||||
return s_s_level;
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw RSSI indicator.
|
||||
* Format: "S:42" or raw dBm with mini bar.
|
||||
* Uses small font to fit in upper-right corner.
|
||||
*/
|
||||
void RSSI_Draw(int x, int y, bool with_bar)
|
||||
{
|
||||
static char buf[16];
|
||||
|
||||
/* Draw dBm value: "-87dBm" */
|
||||
sprintf(buf, "%ddBm", s_rssi_dbm);
|
||||
UI_PrintStringSmallNormal(buf, x, LCD_WIDTH, y);
|
||||
|
||||
if (with_bar) {
|
||||
/* Draw mini signal bar below the text
|
||||
* 5 bars, each 2px wide, 1px gap */
|
||||
int bar_x = x;
|
||||
int bar_y = y + 8;
|
||||
uint8_t bars = (s_s_level + 1) / 2; /* 0-5 bars from S0-S9 */
|
||||
if (bars > 5) bars = 5;
|
||||
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
uint8_t h = 2 + i * 2; /* Bar heights: 2,4,6,8,10 */
|
||||
if (i < bars) {
|
||||
/* Draw filled bar */
|
||||
for (uint8_t py = 0; py < h; py++) {
|
||||
for (uint8_t px = 0; px < 2; px++) {
|
||||
UI_DrawPixelBuffer(gFrameBuffer, bar_x + i * 3 + px, bar_y + (10 - h) + py, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Draw outline only */
|
||||
UI_DrawPixelBuffer(gFrameBuffer, bar_x + i * 3, bar_y + (10 - h), false);
|
||||
UI_DrawPixelBuffer(gFrameBuffer, bar_x + i * 3 + 1, bar_y + (10 - h), false);
|
||||
UI_DrawPixelBuffer(gFrameBuffer, bar_x + i * 3, bar_y + 9, false);
|
||||
UI_DrawPixelBuffer(gFrameBuffer, bar_x + i * 3 + 1, bar_y + 9, false);
|
||||
UI_DrawPixelBuffer(gFrameBuffer, bar_x + i * 3, bar_y + (10 - h) + 1, false);
|
||||
UI_DrawPixelBuffer(gFrameBuffer, bar_x + i * 3 + 1, bar_y + (10 - h) + 1, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user