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)
129 lines
3.5 KiB
C
129 lines
3.5 KiB
C
/* 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);
|
|
}
|
|
}
|
|
}
|
|
}
|